summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
m---------python/psutil0
-rw-r--r--python/psutil/CREDITS310
-rw-r--r--python/psutil/HISTORY.rst1018
-rw-r--r--python/psutil/INSTALL.rst116
-rw-r--r--python/psutil/LICENSE27
-rw-r--r--python/psutil/MANIFEST.in22
-rw-r--r--python/psutil/Makefile122
-rw-r--r--python/psutil/PKG-INFO434
-rw-r--r--python/psutil/README.rst386
-rw-r--r--python/psutil/TODO167
-rw-r--r--python/psutil/docs/Makefile177
-rw-r--r--python/psutil/docs/README15
-rw-r--r--python/psutil/docs/_static/copybutton.js57
-rw-r--r--python/psutil/docs/_static/favicon.icobin15086 -> 0 bytes
-rw-r--r--python/psutil/docs/_static/logo.pngbin4922 -> 0 bytes
-rw-r--r--python/psutil/docs/_static/sidebar.js161
-rw-r--r--python/psutil/docs/_template/globaltoc.html12
-rw-r--r--python/psutil/docs/_template/indexcontent.html4
-rw-r--r--python/psutil/docs/_template/indexsidebar.html8
-rw-r--r--python/psutil/docs/_template/page.html66
-rw-r--r--python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css187
-rw-r--r--python/psutil/docs/_themes/pydoctheme/theme.conf23
-rw-r--r--python/psutil/docs/conf.py248
-rw-r--r--python/psutil/docs/index.rst1400
-rw-r--r--python/psutil/docs/make.bat242
-rw-r--r--python/psutil/docs/xxx11
-rwxr-xr-xpython/psutil/examples/disk_usage.py62
-rwxr-xr-xpython/psutil/examples/free.py41
-rw-r--r--python/psutil/examples/ifconfig.py78
-rwxr-xr-xpython/psutil/examples/iotop.py179
-rwxr-xr-xpython/psutil/examples/killall.py32
-rwxr-xr-xpython/psutil/examples/meminfo.py68
-rwxr-xr-xpython/psutil/examples/netstat.py64
-rwxr-xr-xpython/psutil/examples/nettop.py165
-rwxr-xr-xpython/psutil/examples/pidof.py53
-rwxr-xr-xpython/psutil/examples/pmap.py57
-rwxr-xr-xpython/psutil/examples/process_detail.py167
-rw-r--r--python/psutil/examples/ps.py81
-rw-r--r--python/psutil/examples/pstree.py71
-rwxr-xr-xpython/psutil/examples/top.py233
-rwxr-xr-xpython/psutil/examples/who.py33
-rw-r--r--python/psutil/make.bat201
-rw-r--r--python/psutil/psutil/__init__.py1887
-rw-r--r--python/psutil/psutil/_common.py246
-rw-r--r--python/psutil/psutil/_compat.py189
-rw-r--r--python/psutil/psutil/_psbsd.py455
-rw-r--r--python/psutil/psutil/_pslinux.py1206
-rw-r--r--python/psutil/psutil/_psosx.py363
-rw-r--r--python/psutil/psutil/_psposix.py156
-rw-r--r--python/psutil/psutil/_pssunos.py553
-rw-r--r--python/psutil/psutil/_psutil_bsd.c2296
-rw-r--r--python/psutil/psutil/_psutil_bsd.h53
-rw-r--r--python/psutil/psutil/_psutil_common.c37
-rw-r--r--python/psutil/psutil/_psutil_common.h10
-rw-r--r--python/psutil/psutil/_psutil_linux.c689
-rw-r--r--python/psutil/psutil/_psutil_linux.h21
-rw-r--r--python/psutil/psutil/_psutil_osx.c1808
-rw-r--r--python/psutil/psutil/_psutil_osx.h41
-rw-r--r--python/psutil/psutil/_psutil_posix.c531
-rw-r--r--python/psutil/psutil/_psutil_posix.h15
-rw-r--r--python/psutil/psutil/_psutil_sunos.c1389
-rw-r--r--python/psutil/psutil/_psutil_sunos.h28
-rw-r--r--python/psutil/psutil/_psutil_windows.c3405
-rw-r--r--python/psutil/psutil/_psutil_windows.h68
-rw-r--r--python/psutil/psutil/_pswindows.py548
-rw-r--r--python/psutil/psutil/arch/bsd/process_info.c265
-rw-r--r--python/psutil/psutil/arch/bsd/process_info.h15
-rw-r--r--python/psutil/psutil/arch/osx/process_info.c281
-rw-r--r--python/psutil/psutil/arch/osx/process_info.h16
-rw-r--r--python/psutil/psutil/arch/windows/glpi.h41
-rw-r--r--python/psutil/psutil/arch/windows/inet_ntop.c41
-rw-r--r--python/psutil/psutil/arch/windows/inet_ntop.h10
-rw-r--r--python/psutil/psutil/arch/windows/ntextapi.h228
-rw-r--r--python/psutil/psutil/arch/windows/process_handles.c533
-rw-r--r--python/psutil/psutil/arch/windows/process_handles.h113
-rw-r--r--python/psutil/psutil/arch/windows/process_info.c435
-rw-r--r--python/psutil/psutil/arch/windows/process_info.h26
-rw-r--r--python/psutil/psutil/arch/windows/security.c228
-rw-r--r--python/psutil/psutil/arch/windows/security.h17
-rw-r--r--python/psutil/setup.cfg5
-rw-r--r--python/psutil/setup.py206
-rw-r--r--python/psutil/test/README.rst21
-rw-r--r--python/psutil/test/_bsd.py252
-rw-r--r--python/psutil/test/_linux.py473
-rw-r--r--python/psutil/test/_osx.py160
-rw-r--r--python/psutil/test/_posix.py258
-rw-r--r--python/psutil/test/_sunos.py48
-rw-r--r--python/psutil/test/_windows.py464
-rw-r--r--python/psutil/test/test_memory_leaks.py445
-rw-r--r--python/psutil/test/test_psutil.py3013
-rw-r--r--python/psutil/tox.ini32
92 files changed, 3 insertions, 30418 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..a9f20c480
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "python/psutil"]
+ path = python/psutil
+ url = https://github.com/giampaolo/psutil.git
diff --git a/python/psutil b/python/psutil
new file mode 160000
+Subproject a0967043b5819b2edc61d9a12306289d5e7f98c
diff --git a/python/psutil/CREDITS b/python/psutil/CREDITS
deleted file mode 100644
index 170751b0a..000000000
--- a/python/psutil/CREDITS
+++ /dev/null
@@ -1,310 +0,0 @@
-Intro
-=====
-
-I would like to recognize some of the people who have been instrumental in the
-development of psutil.
-I'm sure I'm forgetting some people (feel free to email me), but here is a
-short list.
-It's modeled after the Linux CREDITS file where the fields are:
-name (N), e-mail (E), web-address (W), country (C), description (D), (I) issues
-(issue tracker is at https://github.com/giampaolo/psutil/issues).
-Really thanks to all of you.
-
-- Giampaolo
-
-Author
-======
-
-N: Giampaolo Rodola'
-C: Italy
-E: g.rodola@gmail.com
-W: http://grodola.blogspot.com/
-
-Contributors
-============
-
-N: Jay Loden
-C: NJ, USA
-E: jloden@gmail.com
-D: original co-author, initial design/bootstrap and occasional bug fixes
-W: http://www.jayloden.com
-
-N: Jeremy Whitlock
-E: jcscoobyrs@gmail.com
-D: great help with OSX C development.
-I: 125, 150, 174, 206
-
-N: wj32
-E: wj32.64@gmail.com
-D: process username() and get_connections() on Windows
-I: 114, 115
-
-N: Yan Raber
-C: Bologna, Italy
-E: yanraber@gmail.com
-D: help on Windows development (initial version of Process.username())
-
-N: Justin Venus
-E: justin.venus@gmail.com
-D: Solaris support
-I: 18
-
-N: Dave Daeschler
-C: USA
-E: david.daeschler@gmail.com
-W: http://daviddaeschler.com
-D: some contributions to initial design/bootstrap plus occasional bug fixing
-I: 522, 536
-
-N: cjgohlke
-E: cjgohlke@gmail.com
-D: Windows 64 bit support
-I: 107
-
-N: Jeffery Kline
-E: jeffery.kline@gmail.com
-I: 130
-
-N: Grabriel Monnerat
-E: gabrielmonnerat@gmail.com
-I: 146
-
-N: Philip Roberts
-E: philip.roberts@gmail.com
-I: 168
-
-N: jcscoobyrs
-E: jcscoobyrs@gmail.com
-I: 125
-
-N: Sandro Tosi
-E: sandro.tosi@gmail.com
-I: 200, 201
-
-N: Andrew Colin
-E: andrew.colin@gmail.com
-I: 248
-
-N: Amoser
-E: amoser@google.com
-I: 266, 267, 340
-
-N: Matthew Grant
-E: matthewgrant5@gmail.com
-I: 271
-
-N: oweidner
-E: oweidner@cct.lsu.edu
-I: 275
-
-N: Tarek Ziade
-E: ziade.tarek
-I: 281
-
-N: Luca Cipriani
-C: Turin, Italy
-E: luca.opensource@gmail.com
-I: 278
-
-N: Maciej Lach,
-E: maciej.lach@gmail.com
-I: 294
-
-N: James Pye
-E: james.pye@gmail.com
-I: 305, 306
-
-N: Stanchev Emil
-E: stanchev.emil
-I: 314
-
-N: Kim Gräsman
-E: kim.grasman@gmail.com
-D: ...also kindly donated some money.
-I: 316
-
-N: Riccardo Murri
-C: Italy
-I: 318
-
-N: Florent Xicluna
-E: florent.xicluna@gmail.com
-I: 319
-
-N: Michal Spondr
-E: michal.spondr
-I: 313
-
-N: Jean Sebastien
-E: dumbboules@gmail.com
-I: 344
-
-N: Rob Smith
-W: http://www.kormoc.com/
-I: 341
-
-N: Youngsik Kim
-W: https://plus.google.com/101320747613749824490/
-I: 317
-
-N: Gregory Szorc
-W: https://plus.google.com/116873264322260110710/posts
-I: 323
-
-N: André Oriani
-E: aoriani@gmail.com
-I: 361
-
-N: clackwell
-E: clackwell@gmail.com
-I: 356
-
-N: m.malycha
-E: m.malycha@gmail.com
-I: 351
-
-N: John Baldwin
-E: jhb@FreeBSD.org
-I: 370
-
-N: Jan Beich
-E: jbeich@tormail.org
-I: 325
-
-N: floppymaster
-E: floppymaster@gmail.com
-I: 380
-
-N: Arfrever.FTA
-E: Arfrever.FTA@gmail.com
-I: 369, 404
-
-N: danudey
-E: danudey@gmail.com
-I: 386
-
-N: Adrien Fallou
-I: 224
-
-N: Gisle Vanem
-E: gisle.vanem@gmail.com
-I: 411
-
-N: thepyr0
-E: thepyr0@gmail.com
-I: 414
-
-N: John Pankov
-E: john.pankov@gmail.com
-I: 435
-
-N: Matt Good
-W: http://matt-good.net/
-I: 438
-
-N: Ulrich Klank
-E: ulrich.klank@scitics.de
-I: 448
-
-N: Josiah Carlson
-E: josiah.carlson@gmail.com
-I: 451, 452
-
-N: Raymond Hettinger
-D: namedtuple and lru_cache backward compatible implementations.
-
-N: Jason Kirtland
-D: backward compatible implementation of collections.defaultdict.
-
-M: Ken Seeho
-D: @cached_property decorator
-
-N: crusaderky
-E: crusaderky@gmail.com
-I: 470, 477
-
-E: alex@mroja.net
-I: 471
-
-N: Gautam Singh
-E: gautam.singh@gmail.com
-I: 466
-
-E: lhn@hupfeldtit.dk
-I: 476, 479
-
-N: Francois Charron
-E: francois.charron.1@gmail.com
-I: 474
-
-N: Naveed Roudsari
-E: naveed.roudsari@gmail.com
-I: 421
-
-N: Alexander Grothe
-E: Alexander.Grothe@gmail.com
-I: 497
-
-N: Szigeti Gabor Niif
-E: szigeti.gabor.niif@gmail.com
-I: 446
-
-N: msabramo
-E: msabramo@gmail.com
-I: 492
-
-N: Jeff Tang
-W: https://github.com/mrjefftang
-I: 340, 529, 616, 653, 654
-
-N: Yaolong Huang
-E: airekans@gmail.com
-W: http://airekans.github.io/
-I: 530
-
-N: Anders Chrigström
-W: https://github.com/anders-chrigstrom
-I: 496
-
-N: spacewander
-E: spacewanderlzx@gmail.com
-I: 561
-
-N: Sylvain Mouquet
-E: sylvain.mouquet@gmail.com
-I: 565
-
-N: karthikrev
-I: 568
-
-N: Bruno Binet
-E: bruno.binet@gmail.com
-I: 572
-
-N: Gabi Davar
-C: Israel
-W: https://github.com/mindw
-I: 578, 581, 587
-
-N: spacewanderlzx
-C: Guangzhou,China
-E: spacewanderlzx@gmail.com
-I: 555
-
-N: Fabian Groffen
-I: 611, 618
-
-N: desbma
-W: https://github.com/desbma
-C: France
-I: 628
-
-N: John Burnett
-W: http://www.johnburnett.com/
-C: Irvine, CA, US
-I: 614
-
-N: Árni Már Jónsson
-E: Reykjavik, Iceland
-E: https://github.com/arnimarj
-I: 634
diff --git a/python/psutil/HISTORY.rst b/python/psutil/HISTORY.rst
deleted file mode 100644
index 12b985d1e..000000000
--- a/python/psutil/HISTORY.rst
+++ /dev/null
@@ -1,1018 +0,0 @@
-Bug tracker at https://github.com/giampaolo/psutil/issues
-
-3.1.1 - 2015-07-15
-==================
-
-**Bug fixes**
-
-- #645: [Linux] psutil.cpu_times_percent() may produce negative results.
-- #656: 'from psutil import *' does not work.
-
-
-3.1.0 - 2015-07-15
-==================
-
-**Enhancements**
-
-- #534: [Linux] disk_partitions() added support for ZFS filesystems.
-- #646: continuous tests integration for Windows with
- https://ci.appveyor.com/project/giampaolo/psutil.
-- #647: new dev guide:
- https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst
-- #651: continuous code quality test integration with
- https://scrutinizer-ci.com/g/giampaolo/psutil/
-
-**Bug fixes**
-
-- #340: [Windows] Process.open_files() no longer hangs. Instead it uses a
- thred which times out and skips the file handle in case it's taking too long
- to be retrieved. (patch by Jeff Tang, PR #597)
-- #627: [Windows] Process.name() no longer raises AccessDenied for pids owned
- by another user.
-- #636: [Windows] Process.memory_info() raise AccessDenied.
-- #637: [UNIX] raise exception if trying to send signal to Process PID 0 as it
- will affect os.getpid()'s process group instead of PID 0.
-- #639: [Linux] Process.cmdline() can be truncated.
-- #640: [Linux] *connections functions may swallow errors and return an
- incomplete list of connnections.
-- #642: repr() of exceptions is incorrect.
-- #653: [Windows] Add inet_ntop function for Windows XP to support IPv6.
-- #641: [Windows] Replace deprecated string functions with safe equivalents.
-
-
-3.0.1 - 2015-06-18
-==================
-
-**Bug fixes**
-
-- #632: [Linux] better error message if cannot parse process UNIX connections.
-- #634: [Linux] Proces.cmdline() does not include empty string arguments.
-- #635: [UNIX] crash on module import if 'enum' package is installed on python
- < 3.4.
-
-
-3.0.0 - 2015-06-13
-==================
-
-**Enhancements**
-
-- #250: new psutil.net_if_stats() returning NIC statistics (isup, duplex,
- speed, MTU).
-- #376: new psutil.net_if_addrs() returning all NIC addresses a-la ifconfig.
-- #469: on Python >= 3.4 ``IOPRIO_CLASS_*`` and ``*_PRIORITY_CLASS`` constants
- returned by psutil.Process' ionice() and nice() methods are enums instead of
- plain integers.
-- #581: add .gitignore. (patch by Gabi Davar)
-- #582: connection constants returned by psutil.net_connections() and
- psutil.Process.connections() were turned from int to enums on Python > 3.4.
-- #587: Move native extension into the package.
-- #589: Process.cpu_affinity() accepts any kind of iterable (set, tuple, ...),
- not only lists.
-- #594: all deprecated APIs were removed.
-- #599: [Windows] process name() can now be determined for all processes even
- when running as a limited user.
-- #602: pre-commit GIT hook.
-- #629: enhanced support for py.test and nose test discovery and tests run.
-- #616: [Windows] Add inet_ntop function for Windows XP.
-
-**Bug fixes**
-
-- #428: [all UNIXes except Linux] correct handling of zombie processes;
- introduced new ZombieProcess exception class.
-- #512: [BSD] fix segfault in net_connections().
-- #555: [Linux] psutil.users() correctly handles ":0" as an alias for
- "localhost"
-- #579: [Windows] Fixed open_files() for PID>64K.
-- #579: [Windows] fixed many compiler warnings.
-- #585: [FreeBSD] net_connections() may raise KeyError.
-- #586: [FreeBSD] cpu_affinity() segfaults on set in case an invalid CPU
- number is provided.
-- #593: [FreeBSD] Process().memory_maps() segfaults.
-- #606: Process.parent() may swallow NoSuchProcess exceptions.
-- #611: [SunOS] net_io_counters has send and received swapped
-- #614: [Linux]: cpu_count(logical=False) return the number of physical CPUs
- instead of physical cores.
-- #618: [SunOS] swap tests fail on Solaris when run as normal user
-- #628: [Linux] Process.name() truncates process name in case it contains
- spaces or parentheses.
-
-
-2.2.1 - 2015-02-02
-==================
-
-**Bug fixes**
-
-- #496: [Linux] fix "ValueError: ambiguos inode with multiple PIDs references"
- (patch by Bruno Binet)
-
-
-2.2.0 - 2015-01-06
-==================
-
-**Enhancements**
-
-- #521: drop support for Python 2.4 and 2.5.
-- #553: new examples/pstree.py script.
-- #564: C extension version mismatch in case the user messed up with psutil
- installation or with sys.path is now detected at import time.
-- #568: New examples/pidof.py script.
-- #569: [FreeBSD] add support for process CPU affinity.
-
-**Bug fixes**
-
-- #496: [Solaris] can't import psutil.
-- #547: [UNIX] Process.username() may raise KeyError if UID can't be resolved.
-- #551: [Windows] get rid of the unicode hack for net_io_counters() NIC names.
-- #556: [Linux] lots of file handles were left open.
-- #561: [Linux] net_connections() might skip some legitimate UNIX sockets.
- (patch by spacewander)
-- #565: [Windows] use proper encoding for psutil.Process.username() and
- psutil.users(). (patch by Sylvain Mouquet)
-- #567: [Linux] in the alternative implementation of CPU affinity PyList_Append
- and Py_BuildValue return values are not checked.
-- #569: [FreeBSD] fix memory leak in psutil.cpu_count(logical=False).
-- #571: [Linux] Process.open_files() might swallow AccessDenied exceptions and
- return an incomplete list of open files.
-
-
-2.1.3 - 2014-09-26
-==================
-
-- #536: [Linux]: fix "undefined symbol: CPU_ALLOC" compilation error.
-
-
-2.1.2 - 2014-09-21
-==================
-
-**Enhancements**
-
-- #407: project moved from Google Code to Github; code moved from Mercurial
- to Git.
-- #492: use tox to run tests on multiple python versions. (patch by msabramo)
-- #505: [Windows] distribution as wheel packages.
-- #511: new examples/ps.py sample code.
-
-**Bug fixes**
-
-- #340: [Windows] Process.get_open_files() no longer hangs. (patch by
- Jeff Tang)
-- #501: [Windows] disk_io_counters() may return negative values.
-- #503: [Linux] in rare conditions Process exe(), open_files() and
- connections() methods can raise OSError(ESRCH) instead of NoSuchProcess.
-- #504: [Linux] can't build RPM packages via setup.py
-- #506: [Linux] python 2.4 support was broken.
-- #522: [Linux] Process.cpu_affinity() might return EINVAL. (patch by David
- Daeschler)
-- #529: [Windows] Process.exe() may raise unhandled WindowsError exception
- for PIDs 0 and 4. (patch by Jeff Tang)
-- #530: [Linux] psutil.disk_io_counters() may crash on old Linux distros
- (< 2.6.5) (patch by Yaolong Huang)
-- #533: [Linux] Process.memory_maps() may raise TypeError on old Linux distros.
-
-
-2.1.1 - 2014-04-30
-==================
-
-**Bug fixes**
-
-- #446: [Windows] fix encoding error when using net_io_counters() on Python 3.
- (patch by Szigeti Gabor Niif)
-- #460: [Windows] net_io_counters() wraps after 4G.
-- #491: [Linux] psutil.net_connections() exceptions. (patch by Alexander Grothe)
-
-
-2.1.0 - 2014-04-08
-==================
-
-**Enhancements**
-
-- #387: system-wide open connections a-la netstat.
-
-**Bug fixes**
-
-- #421: [Solaris] psutil does not compile on SunOS 5.10 (patch by Naveed
- Roudsari)
-- #489: [Linux] psutil.disk_partitions() return an empty list.
-
-
-2.0.0 - 2014-03-10
-==================
-
-**Enhancements**
-
-- #424: [Windows] installer for Python 3.X 64 bit.
-- #427: number of logical and physical CPUs (psutil.cpu_count()).
-- #447: psutil.wait_procs() timeout parameter is now optional.
-- #452: make Process instances hashable and usable with set()s.
-- #453: tests on Python < 2.7 require unittest2 module.
-- #459: add a make file for running tests and other repetitive tasks (also
- on Windows).
-- #463: make timeout parameter of cpu_percent* functions default to 0.0 'cause
- it's a common trap to introduce slowdowns.
-- #468: move documentation to readthedocs.com.
-- #477: process cpu_percent() is about 30% faster. (suggested by crusaderky)
-- #478: [Linux] almost all APIs are about 30% faster on Python 3.X.
-- #479: long deprecated psutil.error module is gone; exception classes now
- live in "psutil" namespace only.
-
-**Bug fixes**
-
-- #193: psutil.Popen constructor can throw an exception if the spawned process
- terminates quickly.
-- #340: [Windows] process get_open_files() no longer hangs. (patch by
- jtang@vahna.net)
-- #443: [Linux] fix a potential overflow issue for Process.set_cpu_affinity()
- on systems with more than 64 CPUs.
-- #448: [Windows] get_children() and ppid() memory leak (patch by Ulrich
- Klank).
-- #457: [POSIX] pid_exists() always returns True for PID 0.
-- #461: namedtuples are not pickle-able.
-- #466: [Linux] process exe improper null bytes handling. (patch by
- Gautam Singh)
-- #470: wait_procs() might not wait. (patch by crusaderky)
-- #471: [Windows] process exe improper unicode handling. (patch by
- alex@mroja.net)
-- #473: psutil.Popen.wait() does not set returncode attribute.
-- #474: [Windows] Process.cpu_percent() is no longer capped at 100%.
-- #476: [Linux] encoding error for process name and cmdline.
-
-**API changes**
-
-For the sake of consistency a lot of psutil APIs have been renamed.
-In most cases accessing the old names will work but it will cause a
-DeprecationWarning.
-
-- psutil.* module level constants have being replaced by functions:
-
- +-----------------------+-------------------------------+
- | Old name | Replacement |
- +=======================+===============================+
- | psutil.NUM_CPUS | psutil.cpu_cpunt() |
- +-----------------------+-------------------------------+
- | psutil.BOOT_TIME | psutil.boot_time() |
- +-----------------------+-------------------------------+
- | psutil.TOTAL_PHYMEM | psutil.virtual_memory().total |
- +-----------------------+-------------------------------+
-
-- Renamed psutil.* functions:
-
- +--------------------------+-------------------------------+
- | Old name | Replacement |
- +==========================+===============================+
- | - psutil.get_pid_list() | psutil.pids() |
- +--------------------------+-------------------------------+
- | - psutil.get_users() | psutil.users() |
- +--------------------------+-------------------------------+
- | - psutil.get_boot_time() | psutil.boot_time() |
- +--------------------------+-------------------------------+
-
-- All psutil.Process ``get_*`` methods lost the ``get_`` prefix.
- get_ext_memory_info() renamed to memory_info_ex().
- Assuming "p = psutil.Process()":
-
- +--------------------------+----------------------+
- | Old name | Replacement |
- +==========================+======================+
- | p.get_children() | p.children() |
- +--------------------------+----------------------+
- | p.get_connections() | p.connections() |
- +--------------------------+----------------------+
- | p.get_cpu_affinity() | p.cpu_affinity() |
- +--------------------------+----------------------+
- | p.get_cpu_percent() | p.cpu_percent() |
- +--------------------------+----------------------+
- | p.get_cpu_times() | p.cpu_times() |
- +--------------------------+----------------------+
- | p.get_ext_memory_info() | p.memory_info_ex() |
- +--------------------------+----------------------+
- | p.get_io_counters() | p.io_counters() |
- +--------------------------+----------------------+
- | p.get_ionice() | p.ionice() |
- +--------------------------+----------------------+
- | p.get_memory_info() | p.memory_info() |
- +--------------------------+----------------------+
- | p.get_memory_maps() | p.memory_maps() |
- +--------------------------+----------------------+
- | p.get_memory_percent() | p.memory_percent() |
- +--------------------------+----------------------+
- | p.get_nice() | p.nice() |
- +--------------------------+----------------------+
- | p.get_num_ctx_switches() | p.num_ctx_switches() |
- +--------------------------+----------------------+
- | p.get_num_fds() | p.num_fds() |
- +--------------------------+----------------------+
- | p.get_num_threads() | p.num_threads() |
- +--------------------------+----------------------+
- | p.get_open_files() | p.open_files() |
- +--------------------------+----------------------+
- | p.get_rlimit() | p.rlimit() |
- +--------------------------+----------------------+
- | p.get_threads() | p.threads() |
- +--------------------------+----------------------+
- | p.getcwd() | p.cwd() |
- +--------------------------+----------------------+
-
-- All psutil.Process ``set_*`` methods lost the ``set_`` prefix.
- Assuming "p = psutil.Process()":
-
- +----------------------+---------------------------------+
- | Old name | Replacement |
- +======================+=================================+
- | p.set_nice() | p.nice(value) |
- +----------------------+---------------------------------+
- | p.set_ionice() | p.ionice(ioclass, value=None) |
- +----------------------+---------------------------------+
- | p.set_cpu_affinity() | p.cpu_affinity(cpus) |
- +----------------------+---------------------------------+
- | p.set_rlimit() | p.rlimit(resource, limits=None) |
- +----------------------+---------------------------------+
-
-- Except for 'pid' all psutil.Process class properties have been turned into
- methods. This is the only case which there are no aliases.
- Assuming "p = psutil.Process()":
-
- +---------------+-----------------+
- | Old name | Replacement |
- +===============+=================+
- | p.name | p.name() |
- +---------------+-----------------+
- | p.parent | p.parent() |
- +---------------+-----------------+
- | p.ppid | p.ppid() |
- +---------------+-----------------+
- | p.exe | p.exe() |
- +---------------+-----------------+
- | p.cmdline | p.cmdline() |
- +---------------+-----------------+
- | p.status | p.status() |
- +---------------+-----------------+
- | p.uids | p.uids() |
- +---------------+-----------------+
- | p.gids | p.gids() |
- +---------------+-----------------+
- | p.username | p.username() |
- +---------------+-----------------+
- | p.create_time | p.create_time() |
- +---------------+-----------------+
-
-- timeout parameter of cpu_percent* functions defaults to 0.0 instead of 0.1.
-- long deprecated psutil.error module is gone; exception classes now live in
- "psutil" namespace only.
-- Process instances' "retcode" attribute returned by psutil.wait_procs() has
- been renamed to "returncode" for consistency with subprocess.Popen.
-
-
-1.2.1 - 2013-11-25
-==================
-
-**Bug fixes**
-
-- #348: [Windows XP] fixed "ImportError: DLL load failed" occurring on module
- import.
-- #425: [Solaris] crash on import due to failure at determining BOOT_TIME.
-- #443: [Linux] can't set CPU affinity on systems with more than 64 cores.
-
-
-1.2.0 - 2013-11-20
-==================
-
-**Enhancements**
-
-- #439: assume os.getpid() if no argument is passed to psutil.Process
- constructor.
-- #440: new psutil.wait_procs() utility function which waits for multiple
- processes to terminate.
-
-**Bug fixes**
-
-- #348: [Windows XP/Vista] fix "ImportError: DLL load failed" occurring on
- module import.
-
-
-1.1.3 - 2013-11-07
-==================
-
-**Bug fixes**
-
-- #442: [Linux] psutil won't compile on certain version of Linux because of
- missing prlimit(2) syscall.
-
-
-1.1.2 - 2013-10-22
-==================
-
-**Bug fixes**
-
-- #442: [Linux] psutil won't compile on Debian 6.0 because of missing
- prlimit(2) syscall.
-
-
-1.1.1 - 2013-10-08
-==================
-
-**Bug fixes**
-
-- #442: [Linux] psutil won't compile on kernels < 2.6.36 due to missing
- prlimit(2) syscall.
-
-
-1.1.0 - 2013-09-28
-==================
-
-**Enhancements**
-
-- #410: host tar.gz and windows binary files are on PYPI.
-- #412: [Linux] get/set process resource limits.
-- #415: [Windows] Process.get_children() is an order of magnitude faster.
-- #426: [Windows] Process.name is an order of magnitude faster.
-- #431: [UNIX] Process.name is slightly faster because it unnecessarily
- retrieved also process cmdline.
-
-**Bug fixes**
-
-- #391: [Windows] psutil.cpu_times_percent() returns negative percentages.
-- #408: STATUS_* and CONN_* constants don't properly serialize on JSON.
-- #411: [Windows] examples/disk_usage.py may pop-up a GUI error.
-- #413: [Windows] Process.get_memory_info() leaks memory.
-- #414: [Windows] Process.exe on Windows XP may raise ERROR_INVALID_PARAMETER.
-- #416: psutil.disk_usage() doesn't work well with unicode path names.
-- #430: [Linux] process IO counters report wrong number of r/w syscalls.
-- #435: [Linux] psutil.net_io_counters() might report erreneous NIC names.
-- #436: [Linux] psutil.net_io_counters() reports a wrong 'dropin' value.
-
-**API changes**
-
-- #408: turn STATUS_* and CONN_* constants into plain Python strings.
-
-
-1.0.1 - 2013-07-12
-==================
-
-**Bug fixes**
-
-- #405: network_io_counters(pernic=True) no longer works as intended in 1.0.0.
-
-
-1.0.0 - 2013-07-10
-==================
-
-**Enhancements**
-
-- #18: Solaris support (yay!) (thanks Justin Venus)
-- #367: Process.get_connections() 'status' strings are now constants.
-- #380: test suite exits with non-zero on failure. (patch by floppymaster)
-- #391: introduce unittest2 facilities and provide workarounds if unittest2
- is not installed (python < 2.7).
-
-**Bug fixes**
-
-- #374: [Windows] negative memory usage reported if process uses a lot of
- memory.
-- #379: [Linux] Process.get_memory_maps() may raise ValueError.
-- #394: [OSX] Mapped memory regions report incorrect file name.
-- #404: [Linux] sched_*affinity() are implicitly declared. (patch by Arfrever)
-
-**API changes**
-
-- Process.get_connections() 'status' field is no longer a string but a
- constant object (psutil.CONN_*).
-- Process.get_connections() 'local_address' and 'remote_address' fields
- renamed to 'laddr' and 'raddr'.
-- psutil.network_io_counters() renamed to psutil.net_io_counters().
-
-
-0.7.1 - 2013-05-03
-==================
-
-**Bug fixes**
-
-- #325: [BSD] psutil.virtual_memory() can raise SystemError.
- (patch by Jan Beich)
-- #370: [BSD] Process.get_connections() requires root. (patch by John Baldwin)
-- #372: [BSD] different process methods raise NoSuchProcess instead of
- AccessDenied.
-
-
-0.7.0 - 2013-04-12
-==================
-
-**Enhancements**
-
-- #233: code migrated to Mercurial (yay!)
-- #246: psutil.error module is deprecated and scheduled for removal.
-- #328: [Windows] process IO nice/priority support.
-- #359: psutil.get_boot_time()
-- #361: [Linux] psutil.cpu_times() now includes new 'steal', 'guest' and
- 'guest_nice' fields available on recent Linux kernels.
- Also, psutil.cpu_percent() is more accurate.
-- #362: cpu_times_percent() (per-CPU-time utilization as a percentage)
-
-**Bug fixes**
-
-- #234: [Windows] disk_io_counters() fails to list certain disks.
-- #264: [Windows] use of psutil.disk_partitions() may cause a message box to
- appear.
-- #313: [Linux] psutil.virtual_memory() and psutil.swap_memory() can crash on
- certain exotic Linux flavors having an incomplete /proc interface.
- If that's the case we now set the unretrievable stats to 0 and raise a
- RuntimeWarning.
-- #315: [OSX] fix some compilation warnings.
-- #317: [Windows] cannot set process CPU affinity above 31 cores.
-- #319: [Linux] process get_memory_maps() raises KeyError 'Anonymous' on Debian
- squeeze.
-- #321: [UNIX] Process.ppid property is no longer cached as the kernel may set
- the ppid to 1 in case of a zombie process.
-- #323: [OSX] disk_io_counters()'s read_time and write_time parameters were
- reporting microseconds not milliseconds. (patch by Gregory Szorc)
-- #331: Process cmdline is no longer cached after first acces as it may change.
-- #333: [OSX] Leak of Mach ports on OS X (patch by rsesek@google.com)
-- #337: [Linux] process methods not working because of a poor /proc
- implementation will raise NotImplementedError rather than RuntimeError
- and Process.as_dict() will not blow up. (patch by Curtin1060)
-- #338: [Linux] disk_io_counters() fails to find some disks.
-- #339: [FreeBSD] get_pid_list() can allocate all the memory on system.
-- #341: [Linux] psutil might crash on import due to error in retrieving system
- terminals map.
-- #344: [FreeBSD] swap_memory() might return incorrect results due to
- kvm_open(3) not being called. (patch by Jean Sebastien)
-- #338: [Linux] disk_io_counters() fails to find some disks.
-- #351: [Windows] if psutil is compiled with mingw32 (provided installers for
- py2.4 and py2.5 are) disk_io_counters() will fail. (Patch by m.malycha)
-- #353: [OSX] get_users() returns an empty list on OSX 10.8.
-- #356: Process.parent now checks whether parent PID has been reused in which
- case returns None.
-- #365: Process.set_nice() should check PID has not been reused by another
- process.
-- #366: [FreeBSD] get_memory_maps(), get_num_fds(), get_open_files() and
- getcwd() Process methods raise RuntimeError instead of AccessDenied.
-
-**API changes**
-
-- Process.cmdline property is no longer cached after first access.
-- Process.ppid property is no longer cached after first access.
-- [Linux] Process methods not working because of a poor /proc implementation
- will raise NotImplementedError instead of RuntimeError.
-- psutil.error module is deprecated and scheduled for removal.
-
-
-0.6.1 - 2012-08-16
-==================
-
-**Enhancements**
-
-- #316: process cmdline property now makes a better job at guessing the process
- executable from the cmdline.
-
-**Bug fixes**
-
-- #316: process exe was resolved in case it was a symlink.
-- #318: python 2.4 compatibility was broken.
-
-**API changes**
-
-- process exe can now return an empty string instead of raising AccessDenied.
-- process exe is no longer resolved in case it's a symlink.
-
-
-0.6.0 - 2012-08-13
-==================
-
-**Enhancements**
-
-- #216: [POSIX] get_connections() UNIX sockets support.
-- #220: [FreeBSD] get_connections() has been rewritten in C and no longer
- requires lsof.
-- #222: [OSX] add support for process cwd.
-- #261: process extended memory info.
-- #295: [OSX] process executable path is now determined by asking the OS
- instead of being guessed from process cmdline.
-- #297: [OSX] the Process methods below were always raising AccessDenied for
- any process except the current one. Now this is no longer true. Also
- they are 2.5x faster.
- - name
- - get_memory_info()
- - get_memory_percent()
- - get_cpu_times()
- - get_cpu_percent()
- - get_num_threads()
-- #300: examples/pmap.py script.
-- #301: process_iter() now yields processes sorted by their PIDs.
-- #302: process number of voluntary and involuntary context switches.
-- #303: [Windows] the Process methods below were always raising AccessDenied
- for any process not owned by current user. Now this is no longer true:
- - create_time
- - get_cpu_times()
- - get_cpu_percent()
- - get_memory_info()
- - get_memory_percent()
- - get_num_handles()
- - get_io_counters()
-- #305: add examples/netstat.py script.
-- #311: system memory functions has been refactorized and rewritten and now
- provide a more detailed and consistent representation of the system
- memory. New psutil.virtual_memory() function provides the following
- memory amounts:
- - total
- - available
- - percent
- - used
- - active [POSIX]
- - inactive [POSIX]
- - buffers (BSD, Linux)
- - cached (BSD, OSX)
- - wired (OSX, BSD)
- - shared [FreeBSD]
- New psutil.swap_memory() provides:
- - total
- - used
- - free
- - percent
- - sin (no. of bytes the system has swapped in from disk (cumulative))
- - sout (no. of bytes the system has swapped out from disk (cumulative))
- All old memory-related functions are deprecated.
- Also two new example scripts were added: free.py and meminfo.py.
-- #312: psutil.network_io_counters() namedtuple includes 4 new fields:
- errin, errout dropin and dropout, reflecting the number of packets
- dropped and with errors.
-
-**Bugfixes**
-
-- #298: [OSX and BSD] memory leak in get_num_fds().
-- #299: potential memory leak every time PyList_New(0) is used.
-- #303: [Windows] potential heap corruption in get_num_threads() and
- get_status() Process methods.
-- #305: [FreeBSD] psutil can't compile on FreeBSD 9 due to removal of utmp.h.
-- #306: at C level, errors are not checked when invoking Py* functions which
- create or manipulate Python objects leading to potential memory related
- errors and/or segmentation faults.
-- #307: [FreeBSD] values returned by psutil.network_io_counters() are wrong.
-- #308: [BSD / Windows] psutil.virtmem_usage() wasn't actually returning
- information about swap memory usage as it was supposed to do. It does
- now.
-- #309: get_open_files() might not return files which can not be accessed
- due to limited permissions. AccessDenied is now raised instead.
-
-**API changes**
-
-- psutil.phymem_usage() is deprecated (use psutil.virtual_memory())
-- psutil.virtmem_usage() is deprecated (use psutil.swap_memory())
-- psutil.phymem_buffers() on Linux is deprecated (use psutil.virtual_memory())
-- psutil.cached_phymem() on Linux is deprecated (use psutil.virtual_memory())
-- [Windows and BSD] psutil.virtmem_usage() now returns information about swap
- memory instead of virtual memory.
-
-
-0.5.1 - 2012-06-29
-==================
-
-**Enhancements**
-
-- #293: [Windows] process executable path is now determined by asking the OS
- instead of being guessed from process cmdline.
-
-**Bugfixes**
-
-- #292: [Linux] race condition in process files/threads/connections.
-- #294: [Windows] Process CPU affinity is only able to set CPU #0.
-
-
-0.5.0 - 2012-06-27
-==================
-
-**Enhancements**
-
-- #195: [Windows] number of handles opened by process.
-- #209: psutil.disk_partitions() now provides also mount options.
-- #229: list users currently connected on the system (psutil.get_users()).
-- #238: [Linux, Windows] process CPU affinity (get and set).
-- #242: Process.get_children(recursive=True): return all process
- descendants.
-- #245: [POSIX] Process.wait() incrementally consumes less CPU cycles.
-- #257: [Windows] removed Windows 2000 support.
-- #258: [Linux] Process.get_memory_info() is now 0.5x faster.
-- #260: process's mapped memory regions. (Windows patch by wj32.64, OSX patch
- by Jeremy Whitlock)
-- #262: [Windows] psutil.disk_partitions() was slow due to inspecting the
- floppy disk drive also when "all" argument was False.
-- #273: psutil.get_process_list() is deprecated.
-- #274: psutil no longer requires 2to3 at installation time in order to work
- with Python 3.
-- #278: new Process.as_dict() method.
-- #281: ppid, name, exe, cmdline and create_time properties of Process class
- are now cached after being accessed.
-- #282: psutil.STATUS_* constants can now be compared by using their string
- representation.
-- #283: speedup Process.is_running() by caching its return value in case the
- process is terminated.
-- #284: [POSIX] per-process number of opened file descriptors.
-- #287: psutil.process_iter() now caches Process instances between calls.
-- #290: Process.nice property is deprecated in favor of new get_nice() and
- set_nice() methods.
-
-**Bugfixes**
-
-- #193: psutil.Popen constructor can throw an exception if the spawned process
- terminates quickly.
-- #240: [OSX] incorrect use of free() for Process.get_connections().
-- #244: [POSIX] Process.wait() can hog CPU resources if called against a
- process which is not our children.
-- #248: [Linux] psutil.network_io_counters() might return erroneous NIC names.
-- #252: [Windows] process getcwd() erroneously raise NoSuchProcess for
- processes owned by another user. It now raises AccessDenied instead.
-- #266: [Windows] psutil.get_pid_list() only shows 1024 processes.
- (patch by Amoser)
-- #267: [OSX] Process.get_connections() - an erroneous remote address was
- returned. (Patch by Amoser)
-- #272: [Linux] Porcess.get_open_files() - potential race condition can lead to
- unexpected NoSuchProcess exception. Also, we can get incorrect reports
- of not absolutized path names.
-- #275: [Linux] Process.get_io_counters() erroneously raise NoSuchProcess on
- old Linux versions. Where not available it now raises
- NotImplementedError.
-- #286: Process.is_running() doesn't actually check whether PID has been
- reused.
-- #314: Process.get_children() can sometimes return non-children.
-
-**API changes**
-
-- Process.nice property is deprecated in favor of new get_nice() and set_nice()
- methods.
-- psutil.get_process_list() is deprecated.
-- ppid, name, exe, cmdline and create_time properties of Process class are now
- cached after being accessed, meaning NoSuchProcess will no longer be raised
- in case the process is gone in the meantime.
-- psutil.STATUS_* constants can now be compared by using their string
- representation.
-
-
-0.4.1 - 2011-12-14
-==================
-
-**Bugfixes**
-
-- #228: some example scripts were not working with python 3.
-- #230: [Windows / OSX] memory leak in Process.get_connections().
-- #232: [Linux] psutil.phymem_usage() can report erroneous values which are
- different than "free" command.
-- #236: [Windows] memory/handle leak in Process's get_memory_info(),
- suspend() and resume() methods.
-
-
-0.4.0 - 2011-10-29
-==================
-
-**Enhancements**
-
-- #150: network I/O counters. (OSX and Windows patch by Jeremy Whitlock)
-- #154: [FreeBSD] add support for process getcwd()
-- #157: [Windows] provide installer for Python 3.2 64-bit.
-- #198: Process.wait(timeout=0) can now be used to make wait() return
- immediately.
-- #206: disk I/O counters. (OSX and Windows patch by Jeremy Whitlock)
-- #213: examples/iotop.py script.
-- #217: Process.get_connections() now has a "kind" argument to filter
- for connections with different criteria.
-- #221: [FreeBSD] Process.get_open_files has been rewritten in C and no longer
- relies on lsof.
-- #223: examples/top.py script.
-- #227: examples/nettop.py script.
-
-**Bugfixes**
-
-- #135: [OSX] psutil cannot create Process object.
-- #144: [Linux] no longer support 0 special PID.
-- #188: [Linux] psutil import error on Linux ARM architectures.
-- #194: [POSIX] psutil.Process.get_cpu_percent() now reports a percentage over
- 100 on multicore processors.
-- #197: [Linux] Process.get_connections() is broken on platforms not
- supporting IPv6.
-- #200: [Linux] psutil.NUM_CPUS not working on armel and sparc architectures
- and causing crash on module import.
-- #201: [Linux] Process.get_connections() is broken on big-endian
- architectures.
-- #211: Process instance can unexpectedly raise NoSuchProcess if tested for
- equality with another object.
-- #218: [Linux] crash at import time on Debian 64-bit because of a missing
- line in /proc/meminfo.
-- #226: [FreeBSD] crash at import time on FreeBSD 7 and minor.
-
-
-0.3.0 - 2011-07-08
-==================
-
-**Enhancements**
-
-- #125: system per-cpu percentage utilization and times.
-- #163: per-process associated terminal (TTY).
-- #171: added get_phymem() and get_virtmem() functions returning system
- memory information (total, used, free) and memory percent usage.
- total_* avail_* and used_* memory functions are deprecated.
-- #172: disk usage statistics.
-- #174: mounted disk partitions.
-- #179: setuptools is now used in setup.py
-
-**Bugfixes**
-
-- #159: SetSeDebug() does not close handles or unset impersonation on return.
-- #164: [Windows] wait function raises a TimeoutException when a process
- returns -1 .
-- #165: process.status raises an unhandled exception.
-- #166: get_memory_info() leaks handles hogging system resources.
-- #168: psutil.cpu_percent() returns erroneous results when used in
- non-blocking mode. (patch by Philip Roberts)
-- #178: OSX - Process.get_threads() leaks memory
-- #180: [Windows] Process's get_num_threads() and get_threads() methods can
- raise NoSuchProcess exception while process still exists.
-
-
-0.2.1 - 2011-03-20
-==================
-
-**Enhancements**
-
-- #64: per-process I/O counters.
-- #116: per-process wait() (wait for process to terminate and return its exit
- code).
-- #134: per-process get_threads() returning information (id, user and kernel
- times) about threads opened by process.
-- #136: process executable path on FreeBSD is now determined by asking the
- kernel instead of guessing it from cmdline[0].
-- #137: per-process real, effective and saved user and group ids.
-- #140: system boot time.
-- #142: per-process get and set niceness (priority).
-- #143: per-process status.
-- #147: per-process I/O nice (priority) - Linux only.
-- #148: psutil.Popen class which tidies up subprocess.Popen and psutil.Process
- in a unique interface.
-- #152: [OSX] get_process_open_files() implementation has been rewritten
- in C and no longer relies on lsof resulting in a 3x speedup.
-- #153: [OSX] get_process_connection() implementation has been rewritten
- in C and no longer relies on lsof resulting in a 3x speedup.
-
-**Bugfixes**
-
-- #83: process cmdline is empty on OSX 64-bit.
-- #130: a race condition can cause IOError exception be raised on
- Linux if process disappears between open() and subsequent read() calls.
-- #145: WindowsError was raised instead of psutil.AccessDenied when using
- process resume() or suspend() on Windows.
-- #146: 'exe' property on Linux can raise TypeError if path contains NULL
- bytes.
-- #151: exe and getcwd() for PID 0 on Linux return inconsistent data.
-
-**API changes**
-
-- Process "uid" and "gid" properties are deprecated in favor of "uids" and
- "gids" properties.
-
-
-0.2.0 - 2010-11-13
-==================
-
-**Enhancements**
-
-- #79: per-process open files.
-- #88: total system physical cached memory.
-- #88: total system physical memory buffers used by the kernel.
-- #91: per-process send_signal() and terminate() methods.
-- #95: NoSuchProcess and AccessDenied exception classes now provide "pid",
- "name" and "msg" attributes.
-- #97: per-process children.
-- #98: Process.get_cpu_times() and Process.get_memory_info now return
- a namedtuple instead of a tuple.
-- #103: per-process opened TCP and UDP connections.
-- #107: add support for Windows 64 bit. (patch by cjgohlke)
-- #111: per-process executable name.
-- #113: exception messages now include process name and pid.
-- #114: process username Windows implementation has been rewritten in pure
- C and no longer uses WMI resulting in a big speedup. Also, pywin32 is no
- longer required as a third-party dependancy. (patch by wj32)
-- #117: added support for Windows 2000.
-- #123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a
- new 'interval' parameter.
-- #129: per-process number of threads.
-
-**Bugfixes**
-
-- #80: fixed warnings when installing psutil with easy_install.
-- #81: psutil fails to compile with Visual Studio.
-- #94: suspend() raises OSError instead of AccessDenied.
-- #86: psutil didn't compile against FreeBSD 6.x.
-- #102: orphaned process handles obtained by using OpenProcess in C were
- left behind every time Process class was instantiated.
-- #111: path and name Process properties report truncated or erroneous
- values on UNIX.
-- #120: cpu_percent() always returning 100% on OS X.
-- #112: uid and gid properties don't change if process changes effective
- user/group id at some point.
-- #126: ppid, uid, gid, name, exe, cmdline and create_time properties are
- no longer cached and correctly raise NoSuchProcess exception if the process
- disappears.
-
-**API changes**
-
-- psutil.Process.path property is deprecated and works as an alias for "exe"
- property.
-- psutil.Process.kill(): signal argument was removed - to send a signal to the
- process use send_signal(signal) method instead.
-- psutil.Process.get_memory_info() returns a nametuple instead of a tuple.
-- psutil.cpu_times() returns a nametuple instead of a tuple.
-- New psutil.Process methods: get_open_files(), get_connections(),
- send_signal() and terminate().
-- ppid, uid, gid, name, exe, cmdline and create_time properties are no longer
- cached and raise NoSuchProcess exception if process disappears.
-- psutil.cpu_percent() no longer returns immediately (see issue 123).
-- psutil.Process.get_cpu_percent() and psutil.cpu_percent() no longer returns
- immediately by default (see issue 123).
-
-
-0.1.3 - 2010-03-02
-==================
-
-**Enhancements**
-
-- #14: per-process username
-- #51: per-process current working directory (Windows and Linux only)
-- #59: Process.is_running() is now 10 times faster
-- #61: added supoprt for FreeBSD 64 bit
-- #71: implemented suspend/resume process
-- #75: python 3 support
-
-**Bugfixes**
-
-- #36: process cpu_times() and memory_info() functions succeeded also for dead
- processes while a NoSuchProcess exception is supposed to be raised.
-- #48: incorrect size for mib array defined in getcmdargs for BSD
-- #49: possible memory leak due to missing free() on error condition on
-- #50: fixed getcmdargs() memory fragmentation on BSD
-- #55: test_pid_4 was failing on Windows Vista
-- #57: some unit tests were failing on systems where no swap memory is
- available
-- #58: is_running() is now called before kill() to make sure we are going
- to kill the correct process.
-- #73: virtual memory size reported on OS X includes shared library size
-- #77: NoSuchProcess wasn't raised on Process.create_time if kill() was
- used first.
-
-
-0.1.2 - 2009-05-06
-==================
-
-**Enhancements**
-
-- #32: Per-process CPU user/kernel times
-- #33: Process create time
-- #34: Per-process CPU utilization percentage
-- #38: Per-process memory usage (bytes)
-- #41: Per-process memory utilization (percent)
-- #39: System uptime
-- #43: Total system virtual memory
-- #46: Total system physical memory
-- #44: Total system used/free virtual and physical memory
-
-**Bugfixes**
-
-- #36: [Windows] NoSuchProcess not raised when accessing timing methods.
-- #40: test_get_cpu_times() failing on FreeBSD and OS X.
-- #42: [Windows] get_memory_percent() raises AccessDenied.
-
-
-0.1.1 - 2009-03-06
-==================
-
-**Enhancements**
-
-- #4: FreeBSD support for all functions of psutil
-- #9: Process.uid and Process.gid now retrieve process UID and GID.
-- #11: Support for parent/ppid - Process.parent property returns a
- Process object representing the parent process, and Process.ppid returns
- the parent PID.
-- #12 & 15:
- NoSuchProcess exception now raised when creating an object
- for a nonexistent process, or when retrieving information about a process
- that has gone away.
-- #21: AccessDenied exception created for raising access denied errors
- from OSError or WindowsError on individual platforms.
-- #26: psutil.process_iter() function to iterate over processes as
- Process objects with a generator.
-- #?: Process objects can now also be compared with == operator for equality
- (PID, name, command line are compared).
-
-**Bugfixes**
-
-- #16: [Windows] Special case for "System Idle Process" (PID 0) which
- otherwise would return an "invalid parameter" exception.
-- #17: get_process_list() ignores NoSuchProcess and AccessDenied
- exceptions during building of the list.
-- #22: [Windows] Process(0).kill() was failing with an unset exception.
-- #23: Special case for pid_exists(0)
-- #24: [Windows] Process(0).kill() now raises AccessDenied exception instead
- of WindowsError.
-- #30: psutil.get_pid_list() was returning two instances of PID 0 on OSX and
- FreeBSD platforms.
-
-
-0.1.0 - 2009-01-27
-==================
-
-- Initial release.
diff --git a/python/psutil/INSTALL.rst b/python/psutil/INSTALL.rst
deleted file mode 100644
index e518c430e..000000000
--- a/python/psutil/INSTALL.rst
+++ /dev/null
@@ -1,116 +0,0 @@
-============================
-Installing using pip on UNIX
-============================
-
-The easiest way to install psutil on UNIX is by using pip (but first you might
-need to install python header files; see later).
-First install pip::
-
- $ wget https://bootstrap.pypa.io/get-pip.py
- $ python get-pip.py
-
-...then run::
-
- $ pip install psutil
-
-You may need to install gcc and python header files first (see later).
-
-
-=====================
-Installing on Windows
-=====================
-
-Just get the right installer for your Python version and architecture from:
-https://pypi.python.org/pypi/psutil/#downloads
-Since wheels installers are also available you may also use pip.
-
-
-========================================
-Compiling on Windows using Visual Studio
-========================================
-
-In order to compile psutil on Windows you'll need Visual Studio (Mingw32 is
-no longer supported). You must have the same version of Visual Studio used to compile
-your installation of Python, that is::
-
-* Python 2.6: VS 2008
-* Python 2.7: VS 2008
-* Python 3.3, 3.4: VS 2010 (you can download it from `MS website <http://www.visualstudio.com/downloads/download-visual-studio-vs#d-2010-express>`_)
-* Python 3.5: `VS 2015 UP <http://www.visualstudio.com/en-au/news/vs2015-preview-vs>`_
-
-...then run::
-
- setup.py build
-
-...or::
-
- make.bat build
-
-Compiling 64 bit versions of Python 2.6 and 2.7 with VS 2008 requires
-Windows SDK and .NET Framework 3.5 SP1 to be installed first.
-Once you have those run vcvars64.bat, then compile:
-http://stackoverflow.com/questions/11072521/
-
-===================
-Installing on Linux
-===================
-
-gcc is required and so the python headers. They can easily be installed by
-using the distro package manager. For example, on Debian and Ubuntu::
-
- $ sudo apt-get install gcc python-dev
-
-...on Redhat and CentOS::
-
- $ sudo yum install gcc python-devel
-
-Once done, you can build/install psutil with::
-
- $ python setup.py install
-
-
-==================
-Installing on OS X
-==================
-
-OS X installation from source will require gcc which you can obtain as part of
-the 'XcodeTools' installer from Apple. Then you can run the standard distutils
-commands.
-To build only::
-
- $ python setup.py build
-
-To install and build::
-
- $ python setup.py install
-
-
-=====================
-Installing on FreeBSD
-=====================
-
-The same compiler used to install Python must be present on the system in order
-to build modules using distutils. Assuming it is installed, you can build using
-the standard distutils commands.
-
-Build only::
-
- $ python setup.py build
-
-Install and build::
-
- $ python setup.py install
-
-
-========
-Makefile
-========
-
-A makefile is available for both UNIX and Windows (make.bat). It provides
-some automations for the tasks described above and might be preferred over
-using setup.py. With it you can::
-
- $ make install # just install (in --user mode)
- $ make uninstall # uninstall (needs pip)
- $ make test # run tests
- $ make clean # remove installation files
diff --git a/python/psutil/LICENSE b/python/psutil/LICENSE
deleted file mode 100644
index e91b1359a..000000000
--- a/python/psutil/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-psutil is distributed under BSD license reproduced below.
-
-Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the psutil authors nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/python/psutil/MANIFEST.in b/python/psutil/MANIFEST.in
deleted file mode 100644
index d807be289..000000000
--- a/python/psutil/MANIFEST.in
+++ /dev/null
@@ -1,22 +0,0 @@
-include .coveragerc
-include .git-pre-commit
-include .git-pre-commit
-include .gitignore
-include .travis.yml
-include CREDITS
-include HISTORY.rst
-include INSTALL.rst
-include LICENSE
-include make.bat
-include Makefile
-include MANIFEST.in
-include README.rst
-include setup.py
-include TODO
-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*
diff --git a/python/psutil/Makefile b/python/psutil/Makefile
deleted file mode 100644
index 1e4eb4b01..000000000
--- a/python/psutil/Makefile
+++ /dev/null
@@ -1,122 +0,0 @@
-# Shortcuts for various tasks (UNIX only).
-# To use a specific Python version run:
-# $ make install PYTHON=python3.3
-
-# You can set these variables from the command line.
-PYTHON = python
-TSCRIPT = test/test_psutil.py
-
-all: test
-
-clean:
- rm -f `find . -type f -name \*.py[co]`
- rm -f `find . -type f -name \*.so`
- rm -f `find . -type f -name .\*~`
- rm -f `find . -type f -name \*.orig`
- rm -f `find . -type f -name \*.bak`
- rm -f `find . -type f -name \*.rej`
- rm -rf `find . -type d -name __pycache__`
- rm -rf *.core
- rm -rf *.egg-info
- rm -rf *\$testfile*
- rm -rf .coverage
- rm -rf .tox
- rm -rf build
- rm -rf dist
- rm -rf docs/_build
- rm -rf htmlcov
-
-build: clean
- $(PYTHON) setup.py build
- @# copies *.so files in ./psutil directory in order to allow
- @# "import psutil" when using the interactive interpreter from within
- @# this directory.
- $(PYTHON) setup.py build_ext -i
-
-# useful deps which are nice to have while developing / testing
-setup-dev-env:
- python -c "import urllib2; \
- r = urllib2.urlopen('https://bootstrap.pypa.io/get-pip.py'); \
- open('/tmp/get-pip.py', 'w').write(r.read());"
- $(PYTHON) /tmp/get-pip.py --user
- rm /tmp/get-pip.py
- $(PYTHON) -m pip install --user --upgrade pip
- $(PYTHON) -m pip install --user --upgrade \
- coverage \
- flake8 \
- ipaddress \
- ipdb \
- mock==1.0.1 \
- nose \
- pep8 \
- pyflakes \
- sphinx \
- sphinx-pypi-upload \
- unittest2 \
-
-install: build
- $(PYTHON) setup.py install --user
-
-uninstall:
- cd ..; $(PYTHON) -m pip uninstall -y -v psutil
-
-test: install
- $(PYTHON) $(TSCRIPT)
-
-test-process: install
- $(PYTHON) -m unittest -v test.test_psutil.TestProcess
-
-test-system: install
- $(PYTHON) -m unittest -v test.test_psutil.TestSystemAPIs
-
-test-memleaks: install
- $(PYTHON) test/test_memory_leaks.py
-
-# Run a specific test by name; e.g. "make test-by-name disk_" will run
-# all test methods containing "disk_" in their name.
-# Requires "pip install nose".
-test-by-name: install
- @$(PYTHON) -m nose test/test_psutil.py test/_* --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS))
-
-# Same as above but for test_memory_leaks.py script.
-test-memleaks-by-name: install
- @$(PYTHON) -m nose test/test_memory_leaks.py --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS))
-
-coverage: install
- # Note: coverage options are controlled by .coveragerc file
- rm -rf .coverage htmlcov
- $(PYTHON) -m coverage run $(TSCRIPT)
- $(PYTHON) -m coverage report
- @echo "writing results to htmlcov/index.html"
- $(PYTHON) -m coverage html
- $(PYTHON) -m webbrowser -t htmlcov/index.html
-
-pep8:
- @git ls-files | grep \\.py$ | xargs $(PYTHON) -m pep8
-
-pyflakes:
- @export PYFLAKES_NODOCTEST=1 && \
- git ls-files | grep \\.py$ | xargs $(PYTHON) -m pyflakes
-
-flake8:
- @git ls-files | grep \\.py$ | xargs $(PYTHON) -m flake8
-
-# Upload source tarball on https://pypi.python.org/pypi/psutil.
-upload-src: clean
- $(PYTHON) setup.py sdist upload
-
-# Build and upload doc on https://pythonhosted.org/psutil/.
-# Requires "pip install sphinx-pypi-upload".
-upload-doc:
- cd docs; make html
- $(PYTHON) setup.py upload_sphinx --upload-dir=docs/_build/html
-
-# git-tag a new release
-git-tag-release:
- git tag -a release-`python -c "import setup; print(setup.get_version())"` -m `git rev-list HEAD --count`:`git rev-parse --short HEAD`
- echo "done; now run 'git push --follow-tags' to push the new tag on the remote repo"
-
-# install GIT pre-commit hook
-install-git-hooks:
- ln -sf ../../.git-pre-commit .git/hooks/pre-commit
- chmod +x .git/hooks/pre-commit
diff --git a/python/psutil/PKG-INFO b/python/psutil/PKG-INFO
deleted file mode 100644
index e74d33f65..000000000
--- a/python/psutil/PKG-INFO
+++ /dev/null
@@ -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
diff --git a/python/psutil/README.rst b/python/psutil/README.rst
deleted file mode 100644
index 564656146..000000000
--- a/python/psutil/README.rst
+++ /dev/null
@@ -1,386 +0,0 @@
-.. 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>`_
diff --git a/python/psutil/TODO b/python/psutil/TODO
deleted file mode 100644
index a5df809d0..000000000
--- a/python/psutil/TODO
+++ /dev/null
@@ -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
diff --git a/python/psutil/docs/Makefile b/python/psutil/docs/Makefile
deleted file mode 100644
index b23ab4ba8..000000000
--- a/python/psutil/docs/Makefile
+++ /dev/null
@@ -1,177 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = _build
-
-# User-friendly check for sphinx-build
-ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
-endif
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- rm -rf $(BUILDDIR)
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/psutil.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/psutil.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/psutil"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/psutil"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-latexpdfja:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/python/psutil/docs/README b/python/psutil/docs/README
deleted file mode 100644
index 3aaea8a5b..000000000
--- a/python/psutil/docs/README
+++ /dev/null
@@ -1,15 +0,0 @@
-About
-=====
-
-This directory contains the reStructuredText (reST) sources to the psutil
-documentation. You don't need to build them yourself, prebuilt versions are
-available at https://pythonhosted.org/psutil/.
-In case you want, you need to install sphinx first:
-
- $ pip install sphinx
-
-Then run:
-
- $ make html
-
-You'll then have an HTML version of the doc at _build/html/index.html. \ No newline at end of file
diff --git a/python/psutil/docs/_static/copybutton.js b/python/psutil/docs/_static/copybutton.js
deleted file mode 100644
index 5d82c672b..000000000
--- a/python/psutil/docs/_static/copybutton.js
+++ /dev/null
@@ -1,57 +0,0 @@
-$(document).ready(function() {
- /* Add a [>>>] button on the top-right corner of code samples to hide
- * the >>> and ... prompts and the output and thus make the code
- * copyable. */
- var div = $('.highlight-python .highlight,' +
- '.highlight-python3 .highlight')
- var pre = div.find('pre');
-
- // get the styles from the current theme
- pre.parent().parent().css('position', 'relative');
- var hide_text = 'Hide the prompts and output';
- var show_text = 'Show the prompts and output';
- var border_width = pre.css('border-top-width');
- var border_style = pre.css('border-top-style');
- var border_color = pre.css('border-top-color');
- var button_styles = {
- 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
- 'border-color': border_color, 'border-style': border_style,
- 'border-width': border_width, 'color': border_color, 'text-size': '75%',
- 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
- 'border-radius': '0 3px 0 0'
- }
-
- // create and add the button to all the code blocks that contain >>>
- div.each(function(index) {
- var jthis = $(this);
- if (jthis.find('.gp').length > 0) {
- var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
- button.css(button_styles)
- button.attr('title', hide_text);
- jthis.prepend(button);
- }
- // tracebacks (.gt) contain bare text elements that need to be
- // wrapped in a span to work with .nextUntil() (see later)
- jthis.find('pre:has(.gt)').contents().filter(function() {
- return ((this.nodeType == 3) && (this.data.trim().length > 0));
- }).wrap('<span>');
- });
-
- // define the behavior of the button when it's clicked
- $('.copybutton').toggle(
- function() {
- var button = $(this);
- button.parent().find('.go, .gp, .gt').hide();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
- button.css('text-decoration', 'line-through');
- button.attr('title', show_text);
- },
- function() {
- var button = $(this);
- button.parent().find('.go, .gp, .gt').show();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
- button.css('text-decoration', 'none');
- button.attr('title', hide_text);
- });
-});
-
diff --git a/python/psutil/docs/_static/favicon.ico b/python/psutil/docs/_static/favicon.ico
deleted file mode 100644
index c9efc5844..000000000
--- a/python/psutil/docs/_static/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/python/psutil/docs/_static/logo.png b/python/psutil/docs/_static/logo.png
deleted file mode 100644
index 7d975ec9d..000000000
--- a/python/psutil/docs/_static/logo.png
+++ /dev/null
Binary files differ
diff --git a/python/psutil/docs/_static/sidebar.js b/python/psutil/docs/_static/sidebar.js
deleted file mode 100644
index 337696391..000000000
--- a/python/psutil/docs/_static/sidebar.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * sidebar.js
- * ~~~~~~~~~~
- *
- * This script makes the Sphinx sidebar collapsible.
- *
- * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in
- * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
- * collapse and expand the sidebar.
- *
- * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the
- * width of the sidebar and the margin-left of the document are decreased.
- * When the sidebar is expanded the opposite happens. This script saves a
- * per-browser/per-session cookie used to remember the position of the sidebar
- * among the pages. Once the browser is closed the cookie is deleted and the
- * position reset to the default (expanded).
- *
- * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-$(function() {
- // global elements used by the functions.
- // the 'sidebarbutton' element is defined as global after its
- // creation, in the add_sidebar_button function
- var bodywrapper = $('.bodywrapper');
- var sidebar = $('.sphinxsidebar');
- var sidebarwrapper = $('.sphinxsidebarwrapper');
-
- // original margin-left of the bodywrapper and width of the sidebar
- // with the sidebar expanded
- var bw_margin_expanded = bodywrapper.css('margin-left');
- var ssb_width_expanded = sidebar.width();
-
- // margin-left of the bodywrapper and width of the sidebar
- // with the sidebar collapsed
- var bw_margin_collapsed = '.8em';
- var ssb_width_collapsed = '.8em';
-
- // colors used by the current theme
- var dark_color = '#AAAAAA';
- var light_color = '#CCCCCC';
-
- function sidebar_is_collapsed() {
- return sidebarwrapper.is(':not(:visible)');
- }
-
- function toggle_sidebar() {
- if (sidebar_is_collapsed())
- expand_sidebar();
- else
- collapse_sidebar();
- }
-
- function collapse_sidebar() {
- sidebarwrapper.hide();
- sidebar.css('width', ssb_width_collapsed);
- bodywrapper.css('margin-left', bw_margin_collapsed);
- sidebarbutton.css({
- 'margin-left': '0',
- //'height': bodywrapper.height(),
- 'height': sidebar.height(),
- 'border-radius': '5px'
- });
- sidebarbutton.find('span').text('»');
- sidebarbutton.attr('title', _('Expand sidebar'));
- document.cookie = 'sidebar=collapsed';
- }
-
- function expand_sidebar() {
- bodywrapper.css('margin-left', bw_margin_expanded);
- sidebar.css('width', ssb_width_expanded);
- sidebarwrapper.show();
- sidebarbutton.css({
- 'margin-left': ssb_width_expanded-12,
- //'height': bodywrapper.height(),
- 'height': sidebar.height(),
- 'border-radius': '0 5px 5px 0'
- });
- sidebarbutton.find('span').text('«');
- sidebarbutton.attr('title', _('Collapse sidebar'));
- //sidebarwrapper.css({'padding-top':
- // Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)});
- document.cookie = 'sidebar=expanded';
- }
-
- function add_sidebar_button() {
- sidebarwrapper.css({
- 'float': 'left',
- 'margin-right': '0',
- 'width': ssb_width_expanded - 28
- });
- // create the button
- sidebar.append(
- '<div id="sidebarbutton"><span>&laquo;</span></div>'
- );
- var sidebarbutton = $('#sidebarbutton');
- // find the height of the viewport to center the '<<' in the page
- var viewport_height;
- if (window.innerHeight)
- viewport_height = window.innerHeight;
- else
- viewport_height = $(window).height();
- var sidebar_offset = sidebar.offset().top;
-
- var sidebar_height = sidebar.height();
- //var sidebar_height = Math.max(bodywrapper.height(), sidebar.height());
- sidebarbutton.find('span').css({
- 'display': 'block',
- 'margin-top': sidebar_height/2 - 10
- //'margin-top': (viewport_height - sidebar.position().top - 20) / 2
- //'position': 'fixed',
- //'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10
- });
-
- sidebarbutton.click(toggle_sidebar);
- sidebarbutton.attr('title', _('Collapse sidebar'));
- sidebarbutton.css({
- 'border-radius': '0 5px 5px 0',
- 'color': '#444444',
- 'background-color': '#CCCCCC',
- 'font-size': '1.2em',
- 'cursor': 'pointer',
- 'height': sidebar_height,
- 'padding-top': '1px',
- 'padding-left': '1px',
- 'margin-left': ssb_width_expanded - 12
- });
-
- sidebarbutton.hover(
- function () {
- $(this).css('background-color', dark_color);
- },
- function () {
- $(this).css('background-color', light_color);
- }
- );
- }
-
- function set_position_from_cookie() {
- if (!document.cookie)
- return;
- var items = document.cookie.split(';');
- for(var k=0; k<items.length; k++) {
- var key_val = items[k].split('=');
- var key = key_val[0];
- if (key == 'sidebar') {
- var value = key_val[1];
- if ((value == 'collapsed') && (!sidebar_is_collapsed()))
- collapse_sidebar();
- else if ((value == 'expanded') && (sidebar_is_collapsed()))
- expand_sidebar();
- }
- }
- }
-
- add_sidebar_button();
- var sidebarbutton = $('#sidebarbutton');
- set_position_from_cookie();
-});
diff --git a/python/psutil/docs/_template/globaltoc.html b/python/psutil/docs/_template/globaltoc.html
deleted file mode 100644
index f5fbb406c..000000000
--- a/python/psutil/docs/_template/globaltoc.html
+++ /dev/null
@@ -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>
diff --git a/python/psutil/docs/_template/indexcontent.html b/python/psutil/docs/_template/indexcontent.html
deleted file mode 100644
index dd5e7249a..000000000
--- a/python/psutil/docs/_template/indexcontent.html
+++ /dev/null
@@ -1,4 +0,0 @@
-{% extends "defindex.html" %}
-{% block tables %}
-
-{% endblock %}
diff --git a/python/psutil/docs/_template/indexsidebar.html b/python/psutil/docs/_template/indexsidebar.html
deleted file mode 100644
index 903675d10..000000000
--- a/python/psutil/docs/_template/indexsidebar.html
+++ /dev/null
@@ -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>
diff --git a/python/psutil/docs/_template/page.html b/python/psutil/docs/_template/page.html
deleted file mode 100644
index 04b47b415..000000000
--- a/python/psutil/docs/_template/page.html
+++ /dev/null
@@ -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 %} \ No newline at end of file
diff --git a/python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css b/python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css
deleted file mode 100644
index 4196e5582..000000000
--- a/python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css
+++ /dev/null
@@ -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;
-}
diff --git a/python/psutil/docs/_themes/pydoctheme/theme.conf b/python/psutil/docs/_themes/pydoctheme/theme.conf
deleted file mode 100644
index 95b97e536..000000000
--- a/python/psutil/docs/_themes/pydoctheme/theme.conf
+++ /dev/null
@@ -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
diff --git a/python/psutil/docs/conf.py b/python/psutil/docs/conf.py
deleted file mode 100644
index ad880110f..000000000
--- a/python/psutil/docs/conf.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# psutil documentation build configuration file, created by
-# sphinx-quickstart.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import datetime
-import os
-
-
-PROJECT_NAME = "psutil"
-AUTHOR = "Giampaolo Rodola'"
-THIS_YEAR = str(datetime.datetime.utcnow().year)
-HERE = os.path.abspath(os.path.dirname(__file__))
-
-
-def get_version():
- INIT = os.path.abspath(os.path.join(HERE, '../psutil/__init__.py'))
- with open(INIT, 'r') as f:
- for line in f:
- if line.startswith('__version__'):
- ret = eval(line.strip().split(' = ')[1])
- assert ret.count('.') == 2, ret
- for num in ret.split('.'):
- assert num.isdigit(), ret
- return ret
- else:
- raise ValueError("couldn't find version string")
-
-VERSION = get_version()
-
-# If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = ['sphinx.ext.autodoc',
- 'sphinx.ext.coverage',
- 'sphinx.ext.pngmath',
- 'sphinx.ext.viewcode',
- 'sphinx.ext.intersphinx']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_template']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-# source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = PROJECT_NAME
-copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR)
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = VERSION
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-# language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-# today = ''
-# Else, today_fmt is used as the format for a strftime call.
-# today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-# default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-add_function_parentheses = True
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-# add_module_names = True
-
-autodoc_docstring_signature = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-# show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-# modindex_common_prefix = []
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-html_theme = 'pydoctheme'
-html_theme_options = {'collapsiblesidebar': True}
-
-# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = ["_themes"]
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-html_title = "{project} {version} documentation".format(**locals())
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-# html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-# html_logo = 'logo.png'
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-html_favicon = '_static/favicon.ico'
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-html_sidebars = {
- 'index': 'indexsidebar.html',
- '**': ['globaltoc.html',
- 'relations.html',
- 'sourcelink.html',
- 'searchbox.html']
-}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-# html_additional_pages = {
-# 'index': 'indexcontent.html',
-# }
-
-# If false, no module index is generated.
-html_domain_indices = False
-
-# If false, no index is generated.
-html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-# html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-# html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-# html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-# html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-# html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = '%s-doc' % PROJECT_NAME
-
-# -- Options for LaTeX output ------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-# latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-# latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass
-# [howto/manual]).
-latex_documents = [
- ('index', '%s.tex' % PROJECT_NAME,
- '%s documentation' % PROJECT_NAME, AUTHOR),
-]
-
-# The name of an image file (relative to this directory) to place at
-# the top of the title page.
-# latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-# latex_use_parts = False
-
-# If true, show page references after internal links.
-# latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-# latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-# latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-# latex_appendices = []
-
-# If false, no module index is generated.
-# latex_domain_indices = True
-
-
-# -- Options for manual page output ------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', PROJECT_NAME, '%s documentation' % PROJECT_NAME, [AUTHOR], 1)
-]
-
-# If true, show URL addresses after external links.
-# man_show_urls = False
diff --git a/python/psutil/docs/index.rst b/python/psutil/docs/index.rst
deleted file mode 100644
index 443019226..000000000
--- a/python/psutil/docs/index.rst
+++ /dev/null
@@ -1,1400 +0,0 @@
-.. module:: psutil
- :synopsis: psutil module
-.. moduleauthor:: Giampaolo Rodola' <grodola@gmail.com>
-
-.. warning::
-
- This documentation refers to new 2.X version of psutil.
- Instructions on how to port existing 1.2.1 code are
- `here <http://grodola.blogspot.com/2014/01/psutil-20-porting.html>`__.
- Old 1.2.1 documentation is still available
- `here <https://code.google.com/p/psutil/wiki/Documentation>`__.
-
-psutil documentation
-====================
-
-Quick links
------------
-
-* `Home page <https://github.com/giampaolo/psutil>`__
-* `Blog <http://grodola.blogspot.com/search/label/psutil>`__
-* `Forum <http://groups.google.com/group/psutil/topics>`__
-* `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`__
-* `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
-* `Development guide <https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst>`_
-* `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`__
-
-About
------
-
-From project's home page:
-
- psutil (python system and process utilities) is a cross-platform library for
- retrieving information on running
- **processes** and **system utilization** (CPU, memory, disks, network) in
- **Python**.
- It is useful mainly for **system monitoring**, **profiling** and **limiting
- process resources** and **management of running processes**.
- It implements many functionalities offered by command line tools
- such as: *ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice,
- ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap*.
- It currently supports **Linux, Windows, OSX, FreeBSD** and **Sun Solaris**,
- both **32-bit** and **64-bit** architectures, with Python versions from
- **2.6 to 3.4** (users of Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
- `PyPy <http://pypy.org/>`__ is also known to work.
-
-The psutil documentation you're reading is distributed as a single HTML page.
-
-System related functions
-========================
-
-CPU
----
-
-.. function:: cpu_times(percpu=False)
-
- Return system CPU times as a namedtuple.
- Every attribute represents the seconds the CPU has spent in the given mode.
- The attributes availability varies depending on the platform:
-
- - **user**
- - **system**
- - **idle**
- - **nice** *(UNIX)*
- - **iowait** *(Linux)*
- - **irq** *(Linux, FreeBSD)*
- - **softirq** *(Linux)*
- - **steal** *(Linux 2.6.11+)*
- - **guest** *(Linux 2.6.24+)*
- - **guest_nice** *(Linux 3.2.0+)*
-
- When *percpu* is ``True`` return a list of namedtuples for each logical CPU
- on the system.
- First element of the list refers to first CPU, second element to second CPU
- and so on.
- The order of the list is consistent across calls.
- Example output on Linux:
-
- >>> import psutil
- >>> psutil.cpu_times()
- scputimes(user=17411.7, nice=77.99, system=3797.02, idle=51266.57, iowait=732.58, irq=0.01, softirq=142.43, steal=0.0, guest=0.0, guest_nice=0.0)
-
-.. function:: cpu_percent(interval=None, percpu=False)
-
- Return a float representing the current system-wide CPU utilization as a
- percentage. When *interval* is > ``0.0`` compares system CPU times elapsed
- before and after the interval (blocking).
- When *interval* is ``0.0`` or ``None`` compares system CPU times elapsed
- since last call or module import, returning immediately.
- That means the first time this is called it will return a meaningless ``0.0``
- value which you are supposed to ignore.
- In this case is recommended for accuracy that this function be called with at
- least ``0.1`` seconds between calls.
- When *percpu* is ``True`` returns a list of floats representing the
- utilization as a percentage for each CPU.
- First element of the list refers to first CPU, second element to second CPU
- and so on. The order of the list is consistent across calls.
-
- >>> import psutil
- >>> # blocking
- >>> psutil.cpu_percent(interval=1)
- 2.0
- >>> # non-blocking (percentage since last call)
- >>> psutil.cpu_percent(interval=None)
- 2.9
- >>> # blocking, per-cpu
- >>> psutil.cpu_percent(interval=1, percpu=True)
- [2.0, 1.0]
- >>>
-
- .. warning::
-
- the first time this function is called with *interval* = ``0.0`` or ``None``
- it will return a meaningless ``0.0`` value which you are supposed to
- ignore.
-
-.. function:: cpu_times_percent(interval=None, percpu=False)
-
- Same as :func:`cpu_percent()` but provides utilization percentages for each
- specific CPU time as is returned by
- :func:`psutil.cpu_times(percpu=True)<cpu_times()>`.
- *interval* and
- *percpu* arguments have the same meaning as in :func:`cpu_percent()`.
-
- .. warning::
-
- the first time this function is called with *interval* = ``0.0`` or
- ``None`` it will return a meaningless ``0.0`` value which you are supposed
- to ignore.
-
-.. function:: cpu_count(logical=True)
-
- Return the number of logical CPUs in the system (same as
- `os.cpu_count() <http://docs.python.org/3/library/os.html#os.cpu_count>`__
- in Python 3.4).
- If *logical* is ``False`` return the number of physical cores only (hyper
- thread CPUs are excluded). Return ``None`` if undetermined.
-
- >>> import psutil
- >>> psutil.cpu_count()
- 4
- >>> psutil.cpu_count(logical=False)
- 2
- >>>
-
-Memory
-------
-
-.. function:: virtual_memory()
-
- Return statistics about system memory usage as a namedtuple including the
- following fields, expressed in bytes:
-
- - **total**: total physical memory available.
- - **available**: the actual amount of available memory that can be given
- instantly to processes that request more memory in bytes; this is
- calculated by summing different memory values depending on the platform
- (e.g. free + buffers + cached on Linux) and it is supposed to be used to
- monitor actual memory usage in a cross platform fashion.
- - **percent**: the percentage usage calculated as
- ``(total - available) / total * 100``.
- - **used**: memory used, calculated differently depending on the platform and
- designed for informational purposes only.
- - **free**: memory not being used at all (zeroed) that is readily available;
- note that this doesn't reflect the actual memory available (use 'available'
- instead).
-
- Platform-specific fields:
-
- - **active**: (UNIX): memory currently in use or very recently used, and so
- it is in RAM.
- - **inactive**: (UNIX): memory that is marked as not used.
- - **buffers**: (Linux, BSD): cache for things like file system metadata.
- - **cached**: (Linux, BSD): cache for various things.
- - **wired**: (BSD, OSX): memory that is marked to always stay in RAM. It is
- never moved to disk.
- - **shared**: (BSD): memory that may be simultaneously accessed by multiple
- processes.
-
- The sum of **used** and **available** does not necessarily equal **total**.
- On Windows **available** and **free** are the same.
- See `examples/meminfo.py <https://github.com/giampaolo/psutil/blob/master/examples/meminfo.py>`__
- script providing an example on how to convert bytes in a human readable form.
-
- >>> import psutil
- >>> mem = psutil.virtual_memory()
- >>> mem
- svmem(total=8374149120L, available=1247768576L, percent=85.1, used=8246628352L, free=127520768L, active=3208777728, inactive=1133408256, buffers=342413312L, cached=777834496)
- >>>
- >>> THRESHOLD = 100 * 1024 * 1024 # 100MB
- >>> if mem.available <= THRESHOLD:
- ... print("warning")
- ...
- >>>
-
-
-.. function:: swap_memory()
-
- Return system swap memory statistics as a namedtuple including the following
- fields:
-
- * **total**: total swap memory in bytes
- * **used**: used swap memory in bytes
- * **free**: free swap memory in bytes
- * **percent**: the percentage usage calculated as ``(total - available) / total * 100``
- * **sin**: the number of bytes the system has swapped in from disk
- (cumulative)
- * **sout**: the number of bytes the system has swapped out from disk
- (cumulative)
-
- **sin** and **sout** on Windows are meaningless and are always set to ``0``.
- See `examples/meminfo.py <https://github.com/giampaolo/psutil/blob/master/examples/meminfo.py>`__
- script providing an example on how to convert bytes in a human readable form.
-
- >>> import psutil
- >>> psutil.swap_memory()
- sswap(total=2097147904L, used=886620160L, free=1210527744L, percent=42.3, sin=1050411008, sout=1906720768)
-
-Disks
------
-
-.. function:: disk_partitions(all=False)
-
- Return all mounted disk partitions as a list of namedtuples including device,
- mount point and filesystem type, similarly to "df" command on UNIX. If *all*
- parameter is ``False`` return physical devices only (e.g. hard disks, cd-rom
- drives, USB keys) and ignore all others (e.g. memory partitions such as
- `/dev/shm <http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html>`__).
- Namedtuple's **fstype** field is a string which varies depending on the
- platform.
- On Linux it can be one of the values found in /proc/filesystems (e.g.
- ``'ext3'`` for an ext3 hard drive o ``'iso9660'`` for the CD-ROM drive).
- On Windows it is determined via
- `GetDriveType <http://msdn.microsoft.com/en-us/library/aa364939(v=vs.85).aspx>`__
- and can be either ``"removable"``, ``"fixed"``, ``"remote"``, ``"cdrom"``,
- ``"unmounted"`` or ``"ramdisk"``. On OSX and FreeBSD it is retrieved via
- `getfsstat(2) <http://www.manpagez.com/man/2/getfsstat/>`__. See
- `disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
- script providing an example usage.
-
- >>> import psutil
- >>> psutil.disk_partitions()
- [sdiskpart(device='/dev/sda3', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro'),
- sdiskpart(device='/dev/sda7', mountpoint='/home', fstype='ext4', opts='rw')]
-
-.. function:: disk_usage(path)
-
- Return disk usage statistics about the given *path* as a namedtuple including
- **total**, **used** and **free** space expressed in bytes, plus the
- **percentage** usage.
- `OSError <http://docs.python.org/3/library/exceptions.html#OSError>`__ is
- raised if *path* does not exist. See
- `examples/disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
- script providing an example usage. Starting from
- `Python 3.3 <http://bugs.python.org/issue12442>`__ this is also
- available as
- `shutil.disk_usage() <http://docs.python.org/3/library/shutil.html#shutil.disk_usage>`__.
- See
- `disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
- script providing an example usage.
-
- >>> import psutil
- >>> psutil.disk_usage('/')
- sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
-
-.. function:: disk_io_counters(perdisk=False)
-
- Return system-wide disk I/O statistics as a namedtuple including the
- following fields:
-
- - **read_count**: number of reads
- - **write_count**: number of writes
- - **read_bytes**: number of bytes read
- - **write_bytes**: number of bytes written
- - **read_time**: time spent reading from disk (in milliseconds)
- - **write_time**: time spent writing to disk (in milliseconds)
-
- If *perdisk* is ``True`` return the same information for every physical disk
- installed on the system as a dictionary with partition names as the keys and
- the namedtuple described above as the values.
- See `examples/iotop.py <https://github.com/giampaolo/psutil/blob/master/examples/iotop.py>`__
- for an example application.
-
- >>> import psutil
- >>> psutil.disk_io_counters()
- sdiskio(read_count=8141, write_count=2431, read_bytes=290203, write_bytes=537676, read_time=5868, write_time=94922)
- >>>
- >>> psutil.disk_io_counters(perdisk=True)
- {'sda1': sdiskio(read_count=920, write_count=1, read_bytes=2933248, write_bytes=512, read_time=6016, write_time=4),
- 'sda2': sdiskio(read_count=18707, write_count=8830, read_bytes=6060, write_bytes=3443, read_time=24585, write_time=1572),
- 'sdb1': sdiskio(read_count=161, write_count=0, read_bytes=786432, write_bytes=0, read_time=44, write_time=0)}
-
-Network
--------
-
-.. function:: net_io_counters(pernic=False)
-
- Return system-wide network I/O statistics as a namedtuple including the
- following attributes:
-
- - **bytes_sent**: number of bytes sent
- - **bytes_recv**: number of bytes received
- - **packets_sent**: number of packets sent
- - **packets_recv**: number of packets received
- - **errin**: total number of errors while receiving
- - **errout**: total number of errors while sending
- - **dropin**: total number of incoming packets which were dropped
- - **dropout**: total number of outgoing packets which were dropped (always 0
- on OSX and BSD)
-
- If *pernic* is ``True`` return the same information for every network
- interface installed on the system as a dictionary with network interface
- names as the keys and the namedtuple described above as the values.
- See `examples/nettop.py <https://github.com/giampaolo/psutil/blob/master/examples/nettop.py>`__
- for an example application.
-
- >>> import psutil
- >>> psutil.net_io_counters()
- snetio(bytes_sent=14508483, bytes_recv=62749361, packets_sent=84311, packets_recv=94888, errin=0, errout=0, dropin=0, dropout=0)
- >>>
- >>> psutil.net_io_counters(pernic=True)
- {'lo': snetio(bytes_sent=547971, bytes_recv=547971, packets_sent=5075, packets_recv=5075, errin=0, errout=0, dropin=0, dropout=0),
- 'wlan0': snetio(bytes_sent=13921765, bytes_recv=62162574, packets_sent=79097, packets_recv=89648, errin=0, errout=0, dropin=0, dropout=0)}
-
-.. function:: net_connections(kind='inet')
-
- Return system-wide socket connections as a list of namedtuples.
- Every namedtuple provides 7 attributes:
-
- - **fd**: the socket file descriptor, if retrievable, else ``-1``.
- If the connection refers to the current process this may be passed to
- `socket.fromfd() <http://docs.python.org/library/socket.html#socket.fromfd>`__
- to obtain a usable socket object.
- - **family**: the address family, either `AF_INET
- <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
- `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
- or `AF_UNIX <http://docs.python.org//library/socket.html#socket.AF_UNIX>`__.
- - **type**: the address type, either `SOCK_STREAM
- <http://docs.python.org//library/socket.html#socket.SOCK_STREAM>`__ or
- `SOCK_DGRAM
- <http://docs.python.org//library/socket.html#socket.SOCK_DGRAM>`__.
- - **laddr**: the local address as a ``(ip, port)`` tuple or a ``path``
- in case of AF_UNIX sockets.
- - **raddr**: the remote address as a ``(ip, port)`` tuple or an absolute
- ``path`` in case of UNIX sockets.
- When the remote endpoint is not connected you'll get an empty tuple
- (AF_INET*) or ``None`` (AF_UNIX).
- On Linux AF_UNIX sockets will always have this set to ``None``.
- - **status**: represents the status of a TCP connection. The return value
- is one of the :data:`psutil.CONN_* <psutil.CONN_ESTABLISHED>` constants
- (a string).
- For UDP and UNIX sockets this is always going to be
- :const:`psutil.CONN_NONE`.
- - **pid**: the PID of the process which opened the socket, if retrievable,
- else ``None``. On some platforms (e.g. Linux) the availability of this
- field changes depending on process privileges (root is needed).
-
- The *kind* parameter is a string which filters for connections that fit the
- following criteria:
-
- .. table::
-
- +----------------+-----------------------------------------------------+
- | **Kind value** | **Connections using** |
- +================+=====================================================+
- | "inet" | IPv4 and IPv6 |
- +----------------+-----------------------------------------------------+
- | "inet4" | IPv4 |
- +----------------+-----------------------------------------------------+
- | "inet6" | IPv6 |
- +----------------+-----------------------------------------------------+
- | "tcp" | TCP |
- +----------------+-----------------------------------------------------+
- | "tcp4" | TCP over IPv4 |
- +----------------+-----------------------------------------------------+
- | "tcp6" | TCP over IPv6 |
- +----------------+-----------------------------------------------------+
- | "udp" | UDP |
- +----------------+-----------------------------------------------------+
- | "udp4" | UDP over IPv4 |
- +----------------+-----------------------------------------------------+
- | "udp6" | UDP over IPv6 |
- +----------------+-----------------------------------------------------+
- | "unix" | UNIX socket (both UDP and TCP protocols) |
- +----------------+-----------------------------------------------------+
- | "all" | the sum of all the possible families and protocols |
- +----------------+-----------------------------------------------------+
-
- On OSX this function requires root privileges.
- To get per-process connections use :meth:`Process.connections`.
- Also, see
- `netstat.py sample script <https://github.com/giampaolo/psutil/blob/master/examples/netstat.py>`__.
- Example:
-
- >>> import psutil
- >>> psutil.net_connections()
- [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
- pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
- pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
- pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
- ...]
-
- .. note:: (OSX) :class:`psutil.AccessDenied` is always raised unless running
- as root (lsof does the same).
- .. note:: (Solaris) UNIX sockets are not supported.
-
- .. versionadded:: 2.1.0
-
-.. function:: net_if_addrs()
-
- Return the addresses associated to each NIC (network interface card)
- installed on the system as a dictionary whose keys are the NIC names and
- value is a list of namedtuples for each address assigned to the NIC.
- Each namedtuple includes 4 fields:
-
- - **family**
- - **address**
- - **netmask**
- - **broadcast**
-
- *family* can be either
- `AF_INET <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
- `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
- or :const:`psutil.AF_LINK`, which refers to a MAC address.
- *address* is the primary address, *netmask* and *broadcast* may be ``None``.
- Example::
-
- >>> import psutil
- >>> psutil.net_if_addrs()
- {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
- 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
- snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
- snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
- >>>
-
- See also `examples/ifconfig.py <https://github.com/giampaolo/psutil/blob/master/examples/ifconfig.py>`__
- for an example application.
-
- .. note:: if you're interested in others families (e.g. AF_BLUETOOTH) you can
- use the more powerful `netifaces <https://pypi.python.org/pypi/netifaces/>`__
- extension.
-
- .. note:: you can have more than one address of the same family associated
- with each interface (that's why dict values are lists).
-
- *New in 3.0.0*
-
-.. function:: net_if_stats()
-
- Return information about each NIC (network interface card) installed on the
- system as a dictionary whose keys are the NIC names and value is a namedtuple
- with the following fields:
-
- - **isup**
- - **duplex**
- - **speed**
- - **mtu**
-
- *isup* is a boolean indicating whether the NIC is up and running, *duplex*
- can be either :const:`NIC_DUPLEX_FULL`, :const:`NIC_DUPLEX_HALF` or
- :const:`NIC_DUPLEX_UNKNOWN`, *speed* is the NIC speed expressed in mega bits
- (MB), if it can't be determined (e.g. 'localhost') it will be set to ``0``,
- *mtu* is the maximum transmission unit expressed in bytes.
- See also `examples/ifconfig.py <https://github.com/giampaolo/psutil/blob/master/examples/ifconfig.py>`__
- for an example application.
- Example:
-
- >>> import psutil
- >>> psutil.net_if_stats()
- {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
- 'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
-
- *New in 3.0.0*
-
-
-Other system info
------------------
-
-.. function:: users()
-
- Return users currently connected on the system as a list of namedtuples
- including the following fields:
-
- - **user**: the name of the user.
- - **terminal**: the tty or pseudo-tty associated with the user, if any,
- else ``None``.
- - **host**: the host name associated with the entry, if any.
- - **started**: the creation time as a floating point number expressed in
- seconds since the epoch.
-
- Example::
-
- >>> import psutil
- >>> psutil.users()
- [suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
- suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
-
-.. function:: boot_time()
-
- Return the system boot time expressed in seconds since the epoch.
- Example:
-
- .. code-block:: python
-
- >>> import psutil, datetime
- >>> psutil.boot_time()
- 1389563460.0
- >>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
- '2014-01-12 22:51:00'
-
-Processes
-=========
-
-Functions
----------
-
-.. function:: pids()
-
- Return a list of current running PIDs. To iterate over all processes
- :func:`process_iter()` should be preferred.
-
-.. function:: pid_exists(pid)
-
- Check whether the given PID exists in the current process list. This is
- faster than doing ``"pid in psutil.pids()"`` and should be preferred.
-
-.. function:: process_iter()
-
- Return an iterator yielding a :class:`Process` class instance for all running
- processes on the local machine.
- Every instance is only created once and then cached into an internal table
- which is updated every time an element is yielded.
- Cached :class:`Process` instances are checked for identity so that you're
- safe in case a PID has been reused by another process, in which case the
- cached instance is updated.
- This is should be preferred over :func:`psutil.pids()` for iterating over
- processes.
- Sorting order in which processes are returned is
- based on their PID. Example usage::
-
- import psutil
-
- for proc in psutil.process_iter():
- try:
- pinfo = proc.as_dict(attrs=['pid', 'name'])
- except psutil.NoSuchProcess:
- pass
- else:
- print(pinfo)
-
-.. function:: wait_procs(procs, timeout=None, callback=None)
-
- Convenience function which waits for a list of :class:`Process` instances to
- terminate. Return a ``(gone, alive)`` tuple indicating which processes are
- gone and which ones are still alive. The *gone* ones will have a new
- *returncode* attribute indicating process exit status (it may be ``None``).
- ``callback`` is a function which gets called every time a process terminates
- (a :class:`Process` instance is passed as callback argument). Function will
- return as soon as all processes terminate or when timeout occurs. Tipical use
- case is:
-
- - send SIGTERM to a list of processes
- - give them some time to terminate
- - send SIGKILL to those ones which are still alive
-
- Example::
-
- import psutil
-
- def on_terminate(proc):
- print("process {} terminated with exit code {}".format(proc, proc.returncode))
-
- procs = [...] # a list of Process instances
- for p in procs:
- p.terminate()
- gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
- for p in alive:
- p.kill()
-
-Exceptions
-----------
-
-.. class:: Error()
-
- Base exception class. All other exceptions inherit from this one.
-
-.. class:: NoSuchProcess(pid, name=None, msg=None)
-
- Raised by :class:`Process` class methods when no process with the given
- *pid* is found in the current process list or when a process no longer
- exists. "name" is the name the process had before disappearing
- and gets set only if :meth:`Process.name()` was previosly called.
-
-.. class:: ZombieProcess(pid, name=None, ppid=None, msg=None)
-
- This may be raised by :class:`Process` class methods when querying a zombie
- process on UNIX (Windows doesn't have zombie processes). Depending on the
- method called the OS may be able to succeed in retrieving the process
- information or not.
- Note: this is a subclass of :class:`NoSuchProcess` so if you're not
- interested in retrieving zombies (e.g. when using :func:`process_iter()`)
- you can ignore this exception and just catch :class:`NoSuchProcess`.
-
- *New in 3.0.0*
-
-.. class:: AccessDenied(pid=None, name=None, msg=None)
-
- Raised by :class:`Process` class methods when permission to perform an
- action is denied. "name" is the name of the process (may be ``None``).
-
-.. class:: TimeoutExpired(seconds, pid=None, name=None, msg=None)
-
- Raised by :meth:`Process.wait` if timeout expires and process is still
- alive.
-
-Process class
--------------
-
-.. class:: Process(pid=None)
-
- Represents an OS process with the given *pid*. If *pid* is omitted current
- process *pid* (`os.getpid() <http://docs.python.org/library/os.html#os.getpid>`__)
- is used.
- Raise :class:`NoSuchProcess` if *pid* does not exist.
- When accessing methods of this class always be prepared to catch
- :class:`NoSuchProcess` and :class:`AccessDenied` exceptions.
- `hash() <http://docs.python.org/2/library/functions.html#hash>`__ builtin can
- be used against instances of this class in order to identify a process
- univocally over time (the hash is determined by mixing process PID
- and creation time). As such it can also be used with
- `set()s <http://docs.python.org/2/library/stdtypes.html#types-set>`__.
-
- .. warning::
-
- the way this class is bound to a process is uniquely via its **PID**.
- That means that if the :class:`Process` instance is old enough and
- the PID has been reused by another process in the meantime you might end up
- interacting with another process.
- The only exceptions for which process identity is pre-emptively checked
- (via PID + creation time) and guaranteed are for
- :meth:`nice` (set),
- :meth:`ionice` (set),
- :meth:`cpu_affinity` (set),
- :meth:`rlimit` (set),
- :meth:`children`,
- :meth:`parent`,
- :meth:`suspend`
- :meth:`resume`,
- :meth:`send_signal`,
- :meth:`terminate`, and
- :meth:`kill`
- methods.
- To prevent this problem for all other methods you can use
- :meth:`is_running()` before querying the process or use
- :func:`process_iter()` in case you're iterating over all processes.
-
- .. attribute:: pid
-
- The process PID.
-
- .. method:: ppid()
-
- The process parent pid. On Windows the return value is cached after first
- call.
-
- .. method:: name()
-
- The process name. The return value is cached after first call.
-
- .. method:: exe()
-
- The process executable as an absolute path.
- On some systems this may also be an empty string.
- The return value is cached after first call.
-
- .. method:: cmdline()
-
- The command line this process has been called with.
-
- .. method:: create_time()
-
- The process creation time as a floating point number expressed in seconds
- since the epoch, in
- `UTC <http://en.wikipedia.org/wiki/Coordinated_universal_time>`__.
- The return value is cached after first call.
-
- >>> import psutil, datetime
- >>> p = psutil.Process()
- >>> p.create_time()
- 1307289803.47
- >>> datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S")
- '2011-03-05 18:03:52'
-
- .. method:: as_dict(attrs=None, ad_value=None)
-
- Utility method returning process information as a hashable dictionary.
- If *attrs* is specified it must be a list of strings reflecting available
- :class:`Process` class's attribute names (e.g. ``['cpu_times', 'name']``)
- else all public (read only) attributes are assumed. *ad_value* is the
- value which gets assigned to a dict key in case :class:`AccessDenied`
- or :class:`ZombieProcess` exception is raised when retrieving that
- particular process information.
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.as_dict(attrs=['pid', 'name', 'username'])
- {'username': 'giampaolo', 'pid': 12366, 'name': 'python'}
-
- .. versionchanged:: 3.0.0 *ad_value* is used also when incurring into
- :class:`ZombieProcess` exception, not only :class:`AccessDenied`
-
- .. method:: parent()
-
- Utility method which returns the parent process as a :class:`Process`
- object pre-emptively checking whether PID has been reused. If no parent
- PID is known return ``None``.
-
- .. method:: status()
-
- The current process status as a string. The returned string is one of the
- :data:`psutil.STATUS_*<psutil.STATUS_RUNNING>` constants.
-
- .. method:: cwd()
-
- The process current working directory as an absolute path.
-
- .. method:: username()
-
- The name of the user that owns the process. On UNIX this is calculated by
- using real process uid.
-
- .. method:: uids()
-
- The **real**, **effective** and **saved** user ids of this process as a
- namedtuple. This is the same as
- `os.getresuid() <http://docs.python.org//library/os.html#os.getresuid>`__
- but can be used for every process PID.
-
- Availability: UNIX
-
- .. method:: gids()
-
- The **real**, **effective** and **saved** group ids of this process as a
- namedtuple. This is the same as
- `os.getresgid() <http://docs.python.org//library/os.html#os.getresgid>`__
- but can be used for every process PID.
-
- Availability: UNIX
-
- .. method:: terminal()
-
- The terminal associated with this process, if any, else ``None``. This is
- similar to "tty" command but can be used for every process PID.
-
- Availability: UNIX
-
- .. method:: nice(value=None)
-
- Get or set process
- `niceness <blogs.techrepublic.com.com/opensource/?p=140>`__ (priority).
- On UNIX this is a number which usually goes from ``-20`` to ``20``.
- The higher the nice value, the lower the priority of the process.
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.nice(10) # set
- >>> p.nice() # get
- 10
- >>>
-
- Starting from `Python 3.3 <http://bugs.python.org/issue10784>`__ this
- functionality is also available as
- `os.getpriority() <http://docs.python.org/3/library/os.html#os.getpriority>`__
- and
- `os.setpriority() <http://docs.python.org/3/library/os.html#os.setpriority>`__
- (UNIX only).
-
- On Windows this is available as well by using
- `GetPriorityClass <http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx>`__
- and `SetPriorityClass <http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx>`__
- and *value* is one of the
- :data:`psutil.*_PRIORITY_CLASS <psutil.ABOVE_NORMAL_PRIORITY_CLASS>`
- constants.
- Example which increases process priority on Windows:
-
- >>> p.nice(psutil.HIGH_PRIORITY_CLASS)
-
- .. method:: ionice(ioclass=None, value=None)
-
- Get or set
- `process I/O niceness <http://friedcpu.wordpress.com/2007/07/17/why-arent-you-using-ionice-yet/>`__ (priority).
- On Linux *ioclass* is one of the
- :data:`psutil.IOPRIO_CLASS_*<psutil.IOPRIO_CLASS_NONE>` constants.
- *value* is a number which goes from ``0`` to ``7``. The higher the value,
- the lower the I/O priority of the process. On Windows only *ioclass* is
- used and it can be set to ``2`` (normal), ``1`` (low) or ``0`` (very low).
- The example below sets IDLE priority class for the current process,
- meaning it will only get I/O time when no other process needs the disk:
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # set
- >>> p.ionice() # get
- pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
- >>>
-
- On Windows only *ioclass* is used and it can be set to ``2`` (normal),
- ``1`` (low) or ``0`` (very low).
-
- Availability: Linux and Windows > Vista
-
- .. versionchanged:: 3.0.0 on >= Python 3.4 the returned ``ioclass``
- constant is an `enum <https://docs.python.org/3/library/enum.html#module-enum>`__
- instead of a plain integer.
-
- .. method:: rlimit(resource, limits=None)
-
- Get or set process resource limits (see
- `man prlimit <http://linux.die.net/man/2/prlimit>`__). *resource* is one of
- the :data:`psutil.RLIMIT_* <psutil.RLIMIT_INFINITY>` constants.
- *limits* is a ``(soft, hard)`` tuple.
- This is the same as `resource.getrlimit() <http://docs.python.org/library/resource.html#resource.getrlimit>`__
- and `resource.setrlimit() <http://docs.python.org/library/resource.html#resource.setrlimit>`__
- but can be used for every process PID and only on Linux.
- Example:
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> # process may open no more than 128 file descriptors
- >>> p.rlimit(psutil.RLIMIT_NOFILE, (128, 128))
- >>> # process may create files no bigger than 1024 bytes
- >>> p.rlimit(psutil.RLIMIT_FSIZE, (1024, 1024))
- >>> # get
- >>> p.rlimit(psutil.RLIMIT_FSIZE)
- (1024, 1024)
- >>>
-
- Availability: Linux
-
- .. method:: io_counters()
-
- Return process I/O statistics as a namedtuple including the number of read
- and write operations performed by the process and the amount of bytes read
- and written. For Linux refer to
- `/proc filesysem documentation <https://www.kernel.org/doc/Documentation/filesystems/proc.txt>`__.
- On BSD there's apparently no way to retrieve bytes counters, hence ``-1``
- is returned for **read_bytes** and **write_bytes** fields. OSX is not
- supported.
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.io_counters()
- pio(read_count=454556, write_count=3456, read_bytes=110592, write_bytes=0)
-
- Availability: all platforms except OSX and Solaris
-
- .. method:: num_ctx_switches()
-
- The number voluntary and involuntary context switches performed by
- this process.
-
- .. method:: num_fds()
-
- The number of file descriptors used by this process.
-
- Availability: UNIX
-
- .. method:: num_handles()
-
- The number of handles used by this process.
-
- Availability: Windows
-
- .. method:: num_threads()
-
- The number of threads currently used by this process.
-
- .. method:: threads()
-
- Return threads opened by process as a list of namedtuples including thread
- id and thread CPU times (user/system).
-
- .. method:: cpu_times()
-
- Return a tuple whose values are process CPU **user** and **system**
- times which means the amount of time expressed in seconds that a process
- has spent in
- `user / system mode <http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1>`__.
- This is similar to
- `os.times() <http://docs.python.org//library/os.html#os.times>`__
- but can be used for every process PID.
-
- .. method:: cpu_percent(interval=None)
-
- Return a float representing the process CPU utilization as a percentage.
- When *interval* is > ``0.0`` compares process times to system CPU times
- elapsed before and after the interval (blocking). When interval is ``0.0``
- or ``None`` compares process times to system CPU times elapsed since last
- call, returning immediately. That means the first time this is called it
- will return a meaningless ``0.0`` value which you are supposed to ignore.
- In this case is recommended for accuracy that this function be called a
- second time with at least ``0.1`` seconds between calls. Example:
-
- >>> import psutil
- >>> p = psutil.Process()
- >>>
- >>> # blocking
- >>> p.cpu_percent(interval=1)
- 2.0
- >>> # non-blocking (percentage since last call)
- >>> p.cpu_percent(interval=None)
- 2.9
- >>>
-
- .. note::
- a percentage > 100 is legitimate as it can result from a process with
- multiple threads running on different CPU cores.
-
- .. warning::
- the first time this method is called with interval = ``0.0`` or
- ``None`` it will return a meaningless ``0.0`` value which you are
- supposed to ignore.
-
- .. method:: cpu_affinity(cpus=None)
-
- Get or set process current
- `CPU affinity <http://www.linuxjournal.com/article/6799?page=0,0>`__.
- CPU affinity consists in telling the OS to run a certain process on a
- limited set of CPUs only. The number of eligible CPUs can be obtained with
- ``list(range(psutil.cpu_count()))``. On set raises ``ValueError`` in case
- an invalid CPU number is specified.
-
- >>> import psutil
- >>> psutil.cpu_count()
- 4
- >>> p = psutil.Process()
- >>> p.cpu_affinity() # get
- [0, 1, 2, 3]
- >>> p.cpu_affinity([0]) # set; from now on, process will run on CPU #0 only
- >>> p.cpu_affinity()
- [0]
- >>>
- >>> # reset affinity against all CPUs
- >>> all_cpus = list(range(psutil.cpu_count()))
- >>> p.cpu_affinity(all_cpus)
- >>>
-
- Availability: Linux, Windows, BSD
-
- .. versionchanged:: 2.2.0 added support for FreeBSD
-
- .. method:: memory_info()
-
- Return a tuple representing RSS (Resident Set Size) and VMS (Virtual
- Memory Size) in bytes. On UNIX *rss* and *vms* are the same values shown
- by ps. On Windows *rss* and *vms* refer to "Mem Usage" and "VM Size"
- columns of taskmgr.exe. For more detailed memory stats use
- :meth:`memory_info_ex`.
-
- .. method:: memory_info_ex()
-
- Return a namedtuple with variable fields depending on the platform
- representing extended memory information about the process.
- All numbers are expressed in bytes.
-
- +--------+---------+-------+-------+--------------------+
- | Linux | OSX | BSD | SunOS | Windows |
- +========+=========+=======+=======+====================+
- | rss | rss | rss | rss | num_page_faults |
- +--------+---------+-------+-------+--------------------+
- | vms | vms | vms | vms | peak_wset |
- +--------+---------+-------+-------+--------------------+
- | shared | pfaults | text | | wset |
- +--------+---------+-------+-------+--------------------+
- | text | pageins | data | | peak_paged_pool |
- +--------+---------+-------+-------+--------------------+
- | lib | | stack | | paged_pool |
- +--------+---------+-------+-------+--------------------+
- | data | | | | peak_nonpaged_pool |
- +--------+---------+-------+-------+--------------------+
- | dirty | | | | nonpaged_pool |
- +--------+---------+-------+-------+--------------------+
- | | | | | pagefile |
- +--------+---------+-------+-------+--------------------+
- | | | | | peak_pagefile |
- +--------+---------+-------+-------+--------------------+
- | | | | | private |
- +--------+---------+-------+-------+--------------------+
-
- Windows metrics are extracted from
- `PROCESS_MEMORY_COUNTERS_EX <http://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx>`__ structure.
- Example on Linux:
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.memory_info_ex()
- pextmem(rss=15491072, vms=84025344, shared=5206016, text=2555904, lib=0, data=9891840, dirty=0)
-
- .. method:: memory_percent()
-
- Compare physical system memory to process resident memory (RSS) and
- calculate process memory utilization as a percentage.
-
- .. method:: memory_maps(grouped=True)
-
- Return process's mapped memory regions as a list of namedtuples whose
- fields are variable depending on the platform. As such, portable
- applications should rely on namedtuple's `path` and `rss` fields only.
- This method is useful to obtain a detailed representation of process
- memory usage as explained
- `here <http://bmaurer.blogspot.it/2006/03/memory-usage-with-smaps.html>`__.
- If *grouped* is ``True`` the mapped regions with the same *path* are
- grouped together and the different memory fields are summed. If *grouped*
- is ``False`` every mapped region is shown as a single entity and the
- namedtuple will also include the mapped region's address space (*addr*)
- and permission set (*perms*).
- See `examples/pmap.py <https://github.com/giampaolo/psutil/blob/master/examples/pmap.py>`__
- for an example application.
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.memory_maps()
- [pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
- pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
- pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, anonymous=1245, swap=0),
- pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0),
- pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0),
- ...]
- >>>
-
- .. method:: children(recursive=False)
-
- Return the children of this process as a list of :Class:`Process` objects,
- pre-emptively checking whether PID has been reused. If recursive is `True`
- return all the parent descendants.
- Example assuming *A == this process*:
- ::
-
- A ─┐
- │
- ├─ B (child) ─┐
- │ └─ X (grandchild) ─┐
- │ └─ Y (great grandchild)
- ├─ C (child)
- └─ D (child)
-
- >>> p.children()
- B, C, D
- >>> p.children(recursive=True)
- B, X, Y, C, D
-
- Note that in the example above if process X disappears process Y won't be
- returned either as the reference to process A is lost.
-
- .. method:: open_files()
-
- Return regular files opened by process as a list of namedtuples including
- the absolute file name and the file descriptor number (on Windows this is
- always ``-1``). Example:
-
- >>> import psutil
- >>> f = open('file.ext', 'w')
- >>> p = psutil.Process()
- >>> p.open_files()
- [popenfile(path='/home/giampaolo/svn/psutil/file.ext', fd=3)]
-
- .. warning::
- on Windows this is not fully reliable as due to some limitations of the
- Windows API the underlying implementation may hang when retrieving
- certain file handles.
- In order to work around that psutil on Windows Vista (and higher) spawns
- a thread and kills it if it's not responding after 100ms.
- That implies that on Windows this method is not guaranteed to enumerate
- all regular file handles (see full discusion
- `here <https://github.com/giampaolo/psutil/pull/597>`_).
-
- .. warning::
- on FreeBSD this method can return files with a 'null' path (see
- `issue 595 <https://github.com/giampaolo/psutil/pull/595>`_).
-
- .. versionchanged:: 3.1.0 no longer hangs on Windows.
-
- .. method:: connections(kind="inet")
-
- Return socket connections opened by process as a list of namedtuples.
- To get system-wide connections use :func:`psutil.net_connections()`.
- Every namedtuple provides 6 attributes:
-
- - **fd**: the socket file descriptor. This can be passed to
- `socket.fromfd() <http://docs.python.org/library/socket.html#socket.fromfd>`__
- to obtain a usable socket object.
- This is only available on UNIX; on Windows ``-1`` is always returned.
- - **family**: the address family, either `AF_INET
- <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
- `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
- or `AF_UNIX <http://docs.python.org//library/socket.html#socket.AF_UNIX>`__.
- - **type**: the address type, either `SOCK_STREAM
- <http://docs.python.org//library/socket.html#socket.SOCK_STREAM>`__ or
- `SOCK_DGRAM
- <http://docs.python.org//library/socket.html#socket.SOCK_DGRAM>`__.
- - **laddr**: the local address as a ``(ip, port)`` tuple or a ``path``
- in case of AF_UNIX sockets.
- - **raddr**: the remote address as a ``(ip, port)`` tuple or an absolute
- ``path`` in case of UNIX sockets.
- When the remote endpoint is not connected you'll get an empty tuple
- (AF_INET) or ``None`` (AF_UNIX).
- On Linux AF_UNIX sockets will always have this set to ``None``.
- - **status**: represents the status of a TCP connection. The return value
- is one of the :data:`psutil.CONN_* <psutil.CONN_ESTABLISHED>` constants.
- For UDP and UNIX sockets this is always going to be
- :const:`psutil.CONN_NONE`.
-
- The *kind* parameter is a string which filters for connections that fit the
- following criteria:
-
- .. table::
-
- +----------------+-----------------------------------------------------+
- | **Kind value** | **Connections using** |
- +================+=====================================================+
- | "inet" | IPv4 and IPv6 |
- +----------------+-----------------------------------------------------+
- | "inet4" | IPv4 |
- +----------------+-----------------------------------------------------+
- | "inet6" | IPv6 |
- +----------------+-----------------------------------------------------+
- | "tcp" | TCP |
- +----------------+-----------------------------------------------------+
- | "tcp4" | TCP over IPv4 |
- +----------------+-----------------------------------------------------+
- | "tcp6" | TCP over IPv6 |
- +----------------+-----------------------------------------------------+
- | "udp" | UDP |
- +----------------+-----------------------------------------------------+
- | "udp4" | UDP over IPv4 |
- +----------------+-----------------------------------------------------+
- | "udp6" | UDP over IPv6 |
- +----------------+-----------------------------------------------------+
- | "unix" | UNIX socket (both UDP and TCP protocols) |
- +----------------+-----------------------------------------------------+
- | "all" | the sum of all the possible families and protocols |
- +----------------+-----------------------------------------------------+
-
- Example:
-
- >>> import psutil
- >>> p = psutil.Process(1694)
- >>> p.name()
- 'firefox'
- >>> p.connections()
- [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
- pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
- pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
- pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
-
- .. method:: is_running()
-
- Return whether the current process is running in the current process list.
- This is reliable also in case the process is gone and its PID reused by
- another process, therefore it must be preferred over doing
- ``psutil.pid_exists(p.pid)``.
-
- .. note::
- this will return ``True`` also if the process is a zombie
- (``p.status() == psutil.STATUS_ZOMBIE``).
-
- .. method:: send_signal(signal)
-
- Send a signal to process (see
- `signal module <http://docs.python.org//library/signal.html>`__
- constants) pre-emptively checking whether PID has been reused.
- This is the same as ``os.kill(pid, sig)``.
- On Windows only **SIGTERM** is valid and is treated as an alias for
- :meth:`kill()`.
-
- .. method:: suspend()
-
- Suspend process execution with **SIGSTOP** signal pre-emptively checking
- whether PID has been reused.
- On UNIX this is the same as ``os.kill(pid, signal.SIGSTOP)``.
- On Windows this is done by suspending all process threads execution.
-
- .. method:: resume()
-
- Resume process execution with **SIGCONT** signal pre-emptively checking
- whether PID has been reused.
- On UNIX this is the same as ``os.kill(pid, signal.SIGCONT)``.
- On Windows this is done by resuming all process threads execution.
-
- .. method:: terminate()
-
- Terminate the process with **SIGTERM** signal pre-emptively checking
- whether PID has been reused.
- On UNIX this is the same as ``os.kill(pid, signal.SIGTERM)``.
- On Windows this is an alias for :meth:`kill`.
-
- .. method:: kill()
-
- Kill the current process by using **SIGKILL** signal pre-emptively
- checking whether PID has been reused.
- On UNIX this is the same as ``os.kill(pid, signal.SIGKILL)``.
- On Windows this is done by using
- `TerminateProcess <http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx>`__.
-
- .. method:: wait(timeout=None)
-
- Wait for process termination and if the process is a children of the
- current one also return the exit code, else ``None``. On Windows there's
- no such limitation (exit code is always returned). If the process is
- already terminated immediately return ``None`` instead of raising
- :class:`NoSuchProcess`. If *timeout* is specified and process is still
- alive raise :class:`TimeoutExpired` exception. It can also be used in a
- non-blocking fashion by specifying ``timeout=0`` in which case it will
- either return immediately or raise :class:`TimeoutExpired`.
- To wait for multiple processes use :func:`psutil.wait_procs()`.
-
-
-Popen class
------------
-
-.. class:: Popen(*args, **kwargs)
-
- A more convenient interface to stdlib
- `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__.
- It starts a sub process and deals with it exactly as when using
- `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__
- but in addition it also provides all the methods of
- :class:`psutil.Process` class in a single interface.
- For method names common to both classes such as
- :meth:`send_signal() <psutil.Process.send_signal()>`,
- :meth:`terminate() <psutil.Process.terminate()>` and
- :meth:`kill() <psutil.Process.kill()>`
- :class:`psutil.Process` implementation takes precedence.
- For a complete documentation refer to
- `subprocess module documentation <http://docs.python.org/library/subprocess.html>`__.
-
- .. note::
-
- Unlike `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__
- this class pre-emptively checks wheter PID has been reused on
- :meth:`send_signal() <psutil.Process.send_signal()>`,
- :meth:`terminate() <psutil.Process.terminate()>` and
- :meth:`kill() <psutil.Process.kill()>`
- so that you can't accidentally terminate another process, fixing
- http://bugs.python.org/issue6973.
-
- >>> import psutil
- >>> from subprocess import PIPE
- >>>
- >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
- >>> p.name()
- 'python'
- >>> p.username()
- 'giampaolo'
- >>> p.communicate()
- ('hello\n', None)
- >>> p.wait(timeout=2)
- 0
- >>>
-
-Constants
-=========
-
-.. _const-pstatus:
-.. data:: STATUS_RUNNING
- STATUS_SLEEPING
- STATUS_DISK_SLEEP
- STATUS_STOPPED
- STATUS_TRACING_STOP
- STATUS_ZOMBIE
- STATUS_DEAD
- STATUS_WAKE_KILL
- STATUS_WAKING
- STATUS_IDLE
- STATUS_LOCKED
- STATUS_WAITING
-
- A set of strings representing the status of a process.
- Returned by :meth:`psutil.Process.status()`.
-
-.. _const-conn:
-.. data:: CONN_ESTABLISHED
- CONN_SYN_SENT
- CONN_SYN_RECV
- CONN_FIN_WAIT1
- CONN_FIN_WAIT2
- CONN_TIME_WAIT
- CONN_CLOSE
- CONN_CLOSE_WAIT
- CONN_LAST_ACK
- CONN_LISTEN
- CONN_CLOSING
- CONN_NONE
- CONN_DELETE_TCB (Windows)
- CONN_IDLE (Solaris)
- CONN_BOUND (Solaris)
-
- A set of strings representing the status of a TCP connection.
- Returned by :meth:`psutil.Process.connections()` (`status` field).
-
-.. _const-prio:
-.. data:: ABOVE_NORMAL_PRIORITY_CLASS
- BELOW_NORMAL_PRIORITY_CLASS
- HIGH_PRIORITY_CLASS
- IDLE_PRIORITY_CLASS
- NORMAL_PRIORITY_CLASS
- REALTIME_PRIORITY_CLASS
-
- A set of integers representing the priority of a process on Windows (see
- `MSDN documentation <http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx>`__).
- They can be used in conjunction with
- :meth:`psutil.Process.nice()` to get or set process priority.
-
- Availability: Windows
-
- .. versionchanged:: 3.0.0 on Python >= 3.4 these constants are
- `enums <https://docs.python.org/3/library/enum.html#module-enum>`__
- instead of a plain integer.
-
-.. _const-ioprio:
-.. data:: IOPRIO_CLASS_NONE
- IOPRIO_CLASS_RT
- IOPRIO_CLASS_BE
- IOPRIO_CLASS_IDLE
-
- A set of integers representing the I/O priority of a process on Linux. They
- can be used in conjunction with :meth:`psutil.Process.ionice()` to get or set
- process I/O priority.
- *IOPRIO_CLASS_NONE* and *IOPRIO_CLASS_BE* (best effort) is the default for
- any process that hasn't set a specific I/O priority.
- *IOPRIO_CLASS_RT* (real time) means the process is given first access to the
- disk, regardless of what else is going on in the system.
- *IOPRIO_CLASS_IDLE* means the process will get I/O time when no-one else
- needs the disk.
- For further information refer to manuals of
- `ionice <http://linux.die.net/man/1/ionice>`__
- command line utility or
- `ioprio_get <http://linux.die.net/man/2/ioprio_get>`__
- system call.
-
- Availability: Linux
-
- .. versionchanged:: 3.0.0 on Python >= 3.4 thse constants are
- `enums <https://docs.python.org/3/library/enum.html#module-enum>`__
- instead of a plain integer.
-
-.. _const-rlimit:
-.. data:: RLIMIT_INFINITY
- RLIMIT_AS
- RLIMIT_CORE
- RLIMIT_CPU
- RLIMIT_DATA
- RLIMIT_FSIZE
- RLIMIT_LOCKS
- RLIMIT_MEMLOCK
- RLIMIT_MSGQUEUE
- RLIMIT_NICE
- RLIMIT_NOFILE
- RLIMIT_NPROC
- RLIMIT_RSS
- RLIMIT_RTPRIO
- RLIMIT_RTTIME
- RLIMIT_RTPRIO
- RLIMIT_SIGPENDING
- RLIMIT_STACK
-
- Constants used for getting and setting process resource limits to be used in
- conjunction with :meth:`psutil.Process.rlimit()`. See
- `man prlimit <http://linux.die.net/man/2/prlimit>`__ for futher information.
-
- Availability: Linux
-
-.. _const-aflink:
-.. data:: AF_LINK
-
- Constant which identifies a MAC address associated with a network interface.
- To be used in conjunction with :func:`psutil.net_if_addrs()`.
-
- *New in 3.0.0*
-
-.. _const-duplex:
-.. data:: NIC_DUPLEX_FULL
- NIC_DUPLEX_HALF
- NIC_DUPLEX_UNKNOWN
-
- Constants which identifies whether a NIC (network interface card) has full or
- half mode speed. NIC_DUPLEX_FULL means the NIC is able to send and receive
- data (files) simultaneously, NIC_DUPLEX_FULL means the NIC can either send or
- receive data at a time.
- To be used in conjunction with :func:`psutil.net_if_stats()`.
-
- *New in 3.0.0*
-
-Development guide
-=================
-
-If you plan on hacking on psutil (e.g. want to add a new feature or fix a bug)
-take a look at the
-`development guide <https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst>`_.
diff --git a/python/psutil/docs/make.bat b/python/psutil/docs/make.bat
deleted file mode 100644
index 9bc67515c..000000000
--- a/python/psutil/docs/make.bat
+++ /dev/null
@@ -1,242 +0,0 @@
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. xml to make Docutils-native XML files
- echo. pseudoxml to make pseudoxml-XML files for display purposes
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\psutil.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\psutil.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdf" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdfja" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf-ja
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-if "%1" == "xml" (
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
- goto end
-)
-
-if "%1" == "pseudoxml" (
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
- goto end
-)
-
-:end
diff --git a/python/psutil/docs/xxx b/python/psutil/docs/xxx
deleted file mode 100644
index b78d53f2d..000000000
--- a/python/psutil/docs/xxx
+++ /dev/null
@@ -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
-
-
diff --git a/python/psutil/examples/disk_usage.py b/python/psutil/examples/disk_usage.py
deleted file mode 100755
index d8600a8c4..000000000
--- a/python/psutil/examples/disk_usage.py
+++ /dev/null
@@ -1,62 +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.
-
-"""
-List all mounted disk partitions a-la "df -h" command.
-
-$ python examples/disk_usage.py
-Device Total Used Free Use % Type Mount
-/dev/sdb3 18.9G 14.7G 3.3G 77% ext4 /
-/dev/sda6 345.9G 83.8G 244.5G 24% ext4 /home
-/dev/sda1 296.0M 43.1M 252.9M 14% vfat /boot/efi
-/dev/sda2 600.0M 312.4M 287.6M 52% fuseblk /media/Recovery
-"""
-
-import sys
-import os
-import psutil
-
-
-def bytes2human(n):
- # http://code.activestate.com/recipes/578019
- # >>> bytes2human(10000)
- # '9.8K'
- # >>> bytes2human(100001221)
- # '95.4M'
- symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
- prefix = {}
- for i, s in enumerate(symbols):
- prefix[s] = 1 << (i + 1) * 10
- for s in reversed(symbols):
- if n >= prefix[s]:
- value = float(n) / prefix[s]
- return '%.1f%s' % (value, s)
- return "%sB" % n
-
-
-def main():
- templ = "%-17s %8s %8s %8s %5s%% %9s %s"
- print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type",
- "Mount"))
- for part in psutil.disk_partitions(all=False):
- if os.name == 'nt':
- if 'cdrom' in part.opts or part.fstype == '':
- # skip cd-rom drives with no disk in it; they may raise
- # ENOENT, pop-up a Windows GUI error for a non-ready
- # partition or just hang.
- continue
- usage = psutil.disk_usage(part.mountpoint)
- print(templ % (
- part.device,
- bytes2human(usage.total),
- bytes2human(usage.used),
- bytes2human(usage.free),
- int(usage.percent),
- part.fstype,
- part.mountpoint))
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/python/psutil/examples/free.py b/python/psutil/examples/free.py
deleted file mode 100755
index 913ca58a4..000000000
--- a/python/psutil/examples/free.py
+++ /dev/null
@@ -1,41 +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 'free' cmdline utility.
-
-$ python examples/free.py
- total used free shared buffers cache
-Mem: 10125520 8625996 1499524 0 349500 3307836
-Swap: 0 0 0
-"""
-
-import psutil
-
-
-def main():
- virt = psutil.virtual_memory()
- swap = psutil.swap_memory()
- templ = "%-7s %10s %10s %10s %10s %10s %10s"
- print(templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache'))
- print(templ % (
- 'Mem:',
- int(virt.total / 1024),
- int(virt.used / 1024),
- int(virt.free / 1024),
- int(getattr(virt, 'shared', 0) / 1024),
- int(getattr(virt, 'buffers', 0) / 1024),
- int(getattr(virt, 'cached', 0) / 1024)))
- print(templ % (
- 'Swap:', int(swap.total / 1024),
- int(swap.used / 1024),
- int(swap.free / 1024),
- '',
- '',
- ''))
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/ifconfig.py b/python/psutil/examples/ifconfig.py
deleted file mode 100644
index e7a436cc0..000000000
--- a/python/psutil/examples/ifconfig.py
+++ /dev/null
@@ -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()
diff --git a/python/psutil/examples/iotop.py b/python/psutil/examples/iotop.py
deleted file mode 100755
index 16ac7fbf6..000000000
--- a/python/psutil/examples/iotop.py
+++ /dev/null
@@ -1,179 +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 iotop (http://guichaz.free.fr/iotop/) showing real time
-disk I/O statistics.
-
-It works on Linux only (FreeBSD and OSX are missing support for IO
-counters).
-It doesn't work on Windows as curses module is required.
-
-Example output:
-
-$ python examples/iotop.py
-Total DISK READ: 0.00 B/s | Total DISK WRITE: 472.00 K/s
-PID USER DISK READ DISK WRITE COMMAND
-13155 giampao 0.00 B/s 428.00 K/s /usr/bin/google-chrome-beta
-3260 giampao 0.00 B/s 0.00 B/s bash
-3779 giampao 0.00 B/s 0.00 B/s gnome-session --session=ubuntu
-3830 giampao 0.00 B/s 0.00 B/s /usr/bin/dbus-launch
-3831 giampao 0.00 B/s 0.00 B/s //bin/dbus-daemon --fork --print-pid 5
-3841 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi-bus-launcher
-3845 giampao 0.00 B/s 0.00 B/s /bin/dbus-daemon
-3848 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi2-core/at-spi2-registryd
-3862 giampao 0.00 B/s 0.00 B/s /usr/lib/gnome-settings-daemon
-
-Author: Giampaolo Rodola' <g.rodola@gmail.com>
-"""
-
-import atexit
-import time
-import sys
-try:
- import curses
-except ImportError:
- sys.exit('platform not supported')
-
-import psutil
-
-
-# --- curses stuff
-def tear_down():
- win.keypad(0)
- curses.nocbreak()
- curses.echo()
- curses.endwin()
-
-win = curses.initscr()
-atexit.register(tear_down)
-curses.endwin()
-lineno = 0
-
-
-def print_line(line, highlight=False):
- """A thin wrapper around curses's addstr()."""
- global lineno
- try:
- if highlight:
- line += " " * (win.getmaxyx()[1] - len(line))
- win.addstr(lineno, 0, line, curses.A_REVERSE)
- else:
- win.addstr(lineno, 0, line, 0)
- except curses.error:
- lineno = 0
- win.refresh()
- raise
- else:
- lineno += 1
-# --- /curses stuff
-
-
-def bytes2human(n):
- """
- >>> bytes2human(10000)
- '9.8 K/s'
- >>> bytes2human(100001221)
- '95.4 M/s'
- """
- symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
- prefix = {}
- for i, s in enumerate(symbols):
- prefix[s] = 1 << (i + 1) * 10
- for s in reversed(symbols):
- if n >= prefix[s]:
- value = float(n) / prefix[s]
- return '%.2f %s/s' % (value, s)
- return '%.2f B/s' % (n)
-
-
-def poll(interval):
- """Calculate IO usage by comparing IO statics before and
- after the interval.
- Return a tuple including all currently running processes
- sorted by IO activity and total disks I/O activity.
- """
- # first get a list of all processes and disk io counters
- procs = [p for p in psutil.process_iter()]
- for p in procs[:]:
- try:
- p._before = p.io_counters()
- except psutil.Error:
- procs.remove(p)
- continue
- disks_before = psutil.disk_io_counters()
-
- # sleep some time
- time.sleep(interval)
-
- # then retrieve the same info again
- for p in procs[:]:
- try:
- p._after = p.io_counters()
- p._cmdline = ' '.join(p.cmdline())
- if not p._cmdline:
- p._cmdline = p.name()
- p._username = p.username()
- except (psutil.NoSuchProcess, psutil.ZombieProcess):
- procs.remove(p)
- disks_after = psutil.disk_io_counters()
-
- # finally calculate results by comparing data before and
- # after the interval
- for p in procs:
- p._read_per_sec = p._after.read_bytes - p._before.read_bytes
- p._write_per_sec = p._after.write_bytes - p._before.write_bytes
- p._total = p._read_per_sec + p._write_per_sec
-
- disks_read_per_sec = disks_after.read_bytes - disks_before.read_bytes
- disks_write_per_sec = disks_after.write_bytes - disks_before.write_bytes
-
- # sort processes by total disk IO so that the more intensive
- # ones get listed first
- processes = sorted(procs, key=lambda p: p._total, reverse=True)
-
- return (processes, disks_read_per_sec, disks_write_per_sec)
-
-
-def refresh_window(procs, disks_read, disks_write):
- """Print results on screen by using curses."""
- curses.endwin()
- templ = "%-5s %-7s %11s %11s %s"
- win.erase()
-
- disks_tot = "Total DISK READ: %s | Total DISK WRITE: %s" \
- % (bytes2human(disks_read), bytes2human(disks_write))
- print_line(disks_tot)
-
- header = templ % ("PID", "USER", "DISK READ", "DISK WRITE", "COMMAND")
- print_line(header, highlight=True)
-
- for p in procs:
- line = templ % (
- p.pid,
- p._username[:7],
- bytes2human(p._read_per_sec),
- bytes2human(p._write_per_sec),
- p._cmdline)
- try:
- print_line(line)
- except curses.error:
- break
- win.refresh()
-
-
-def main():
- try:
- interval = 0
- while True:
- args = poll(interval)
- refresh_window(*args)
- interval = 1
- except (KeyboardInterrupt, SystemExit):
- pass
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/killall.py b/python/psutil/examples/killall.py
deleted file mode 100755
index b548e7bc5..000000000
--- a/python/psutil/examples/killall.py
+++ /dev/null
@@ -1,32 +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.
-
-"""
-Kill a process by name.
-"""
-
-import os
-import sys
-import psutil
-
-
-def main():
- if len(sys.argv) != 2:
- sys.exit('usage: %s name' % __file__)
- else:
- NAME = sys.argv[1]
-
- killed = []
- for proc in psutil.process_iter():
- if proc.name() == NAME and proc.pid != os.getpid():
- proc.kill()
- killed.append(proc.pid)
- if not killed:
- sys.exit('%s: no process found' % NAME)
- else:
- sys.exit(0)
-
-sys.exit(main())
diff --git a/python/psutil/examples/meminfo.py b/python/psutil/examples/meminfo.py
deleted file mode 100755
index c463a3de4..000000000
--- a/python/psutil/examples/meminfo.py
+++ /dev/null
@@ -1,68 +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 system memory information.
-
-$ python examples/meminfo.py
-MEMORY
-------
-Total : 9.7G
-Available : 4.9G
-Percent : 49.0
-Used : 8.2G
-Free : 1.4G
-Active : 5.6G
-Inactive : 2.1G
-Buffers : 341.2M
-Cached : 3.2G
-
-SWAP
-----
-Total : 0B
-Used : 0B
-Free : 0B
-Percent : 0.0
-Sin : 0B
-Sout : 0B
-"""
-
-import psutil
-
-
-def bytes2human(n):
- # http://code.activestate.com/recipes/578019
- # >>> bytes2human(10000)
- # '9.8K'
- # >>> bytes2human(100001221)
- # '95.4M'
- symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
- prefix = {}
- for i, s in enumerate(symbols):
- prefix[s] = 1 << (i + 1) * 10
- for s in reversed(symbols):
- if n >= prefix[s]:
- value = float(n) / prefix[s]
- return '%.1f%s' % (value, s)
- return "%sB" % n
-
-
-def pprint_ntuple(nt):
- for name in nt._fields:
- value = getattr(nt, name)
- if name != 'percent':
- value = bytes2human(value)
- print('%-10s : %7s' % (name.capitalize(), value))
-
-
-def main():
- print('MEMORY\n------')
- pprint_ntuple(psutil.virtual_memory())
- print('\nSWAP\n----')
- pprint_ntuple(psutil.swap_memory())
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/netstat.py b/python/psutil/examples/netstat.py
deleted file mode 100755
index 884622e9e..000000000
--- a/python/psutil/examples/netstat.py
+++ /dev/null
@@ -1,64 +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 'netstat -antp' on Linux.
-
-$ python examples/netstat.py
-Proto Local address Remote address Status PID Program name
-tcp 127.0.0.1:48256 127.0.0.1:45884 ESTABLISHED 13646 chrome
-tcp 127.0.0.1:47073 127.0.0.1:45884 ESTABLISHED 13646 chrome
-tcp 127.0.0.1:47072 127.0.0.1:45884 ESTABLISHED 13646 chrome
-tcp 127.0.0.1:45884 - LISTEN 13651 GoogleTalkPlugi
-tcp 127.0.0.1:60948 - LISTEN 13651 GoogleTalkPlugi
-tcp 172.17.42.1:49102 127.0.0.1:19305 CLOSE_WAIT 13651 GoogleTalkPlugi
-tcp 172.17.42.1:55797 127.0.0.1:443 CLOSE_WAIT 13651 GoogleTalkPlugi
-...
-"""
-
-import socket
-from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
-
-import psutil
-
-
-AD = "-"
-AF_INET6 = getattr(socket, 'AF_INET6', object())
-proto_map = {
- (AF_INET, SOCK_STREAM): 'tcp',
- (AF_INET6, SOCK_STREAM): 'tcp6',
- (AF_INET, SOCK_DGRAM): 'udp',
- (AF_INET6, SOCK_DGRAM): 'udp6',
-}
-
-
-def main():
- templ = "%-5s %-30s %-30s %-13s %-6s %s"
- print(templ % (
- "Proto", "Local address", "Remote address", "Status", "PID",
- "Program name"))
- proc_names = {}
- for p in psutil.process_iter():
- try:
- proc_names[p.pid] = p.name()
- except psutil.Error:
- pass
- for c in psutil.net_connections(kind='inet'):
- laddr = "%s:%s" % (c.laddr)
- raddr = ""
- if c.raddr:
- raddr = "%s:%s" % (c.raddr)
- print(templ % (
- proto_map[(c.family, c.type)],
- laddr,
- raddr or AD,
- c.status,
- c.pid or AD,
- proc_names.get(c.pid, '?')[:15],
- ))
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/nettop.py b/python/psutil/examples/nettop.py
deleted file mode 100755
index 7a8343ee4..000000000
--- a/python/psutil/examples/nettop.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/env python
-#
-# $Id: iotop.py 1160 2011-10-14 18:50:36Z g.rodola@gmail.com $
-#
-# 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.
-
-"""
-Shows real-time network statistics.
-
-Author: Giampaolo Rodola' <g.rodola@gmail.com>
-
-$ python examples/nettop.py
------------------------------------------------------------
-total bytes: sent: 1.49 G received: 4.82 G
-total packets: sent: 7338724 received: 8082712
-
-wlan0 TOTAL PER-SEC
------------------------------------------------------------
-bytes-sent 1.29 G 0.00 B/s
-bytes-recv 3.48 G 0.00 B/s
-pkts-sent 7221782 0
-pkts-recv 6753724 0
-
-eth1 TOTAL PER-SEC
------------------------------------------------------------
-bytes-sent 131.77 M 0.00 B/s
-bytes-recv 1.28 G 0.00 B/s
-pkts-sent 0 0
-pkts-recv 1214470 0
-"""
-
-import atexit
-import time
-import sys
-try:
- import curses
-except ImportError:
- sys.exit('platform not supported')
-
-import psutil
-
-
-# --- curses stuff
-def tear_down():
- win.keypad(0)
- curses.nocbreak()
- curses.echo()
- curses.endwin()
-
-win = curses.initscr()
-atexit.register(tear_down)
-curses.endwin()
-lineno = 0
-
-
-def print_line(line, highlight=False):
- """A thin wrapper around curses's addstr()."""
- global lineno
- try:
- if highlight:
- line += " " * (win.getmaxyx()[1] - len(line))
- win.addstr(lineno, 0, line, curses.A_REVERSE)
- else:
- win.addstr(lineno, 0, line, 0)
- except curses.error:
- lineno = 0
- win.refresh()
- raise
- else:
- lineno += 1
-# --- curses stuff
-
-
-def bytes2human(n):
- """
- >>> bytes2human(10000)
- '9.8 K'
- >>> bytes2human(100001221)
- '95.4 M'
- """
- symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
- prefix = {}
- for i, s in enumerate(symbols):
- prefix[s] = 1 << (i + 1) * 10
- for s in reversed(symbols):
- if n >= prefix[s]:
- value = float(n) / prefix[s]
- return '%.2f %s' % (value, s)
- return '%.2f B' % (n)
-
-
-def poll(interval):
- """Retrieve raw stats within an interval window."""
- tot_before = psutil.net_io_counters()
- pnic_before = psutil.net_io_counters(pernic=True)
- # sleep some time
- time.sleep(interval)
- tot_after = psutil.net_io_counters()
- pnic_after = psutil.net_io_counters(pernic=True)
- return (tot_before, tot_after, pnic_before, pnic_after)
-
-
-def refresh_window(tot_before, tot_after, pnic_before, pnic_after):
- """Print stats on screen."""
- global lineno
-
- # totals
- print_line("total bytes: sent: %-10s received: %s" % (
- bytes2human(tot_after.bytes_sent),
- bytes2human(tot_after.bytes_recv))
- )
- print_line("total packets: sent: %-10s received: %s" % (
- tot_after.packets_sent, tot_after.packets_recv))
-
- # per-network interface details: let's sort network interfaces so
- # that the ones which generated more traffic are shown first
- print_line("")
- nic_names = list(pnic_after.keys())
- nic_names.sort(key=lambda x: sum(pnic_after[x]), reverse=True)
- for name in nic_names:
- stats_before = pnic_before[name]
- stats_after = pnic_after[name]
- templ = "%-15s %15s %15s"
- print_line(templ % (name, "TOTAL", "PER-SEC"), highlight=True)
- print_line(templ % (
- "bytes-sent",
- bytes2human(stats_after.bytes_sent),
- bytes2human(
- stats_after.bytes_sent - stats_before.bytes_sent) + '/s',
- ))
- print_line(templ % (
- "bytes-recv",
- bytes2human(stats_after.bytes_recv),
- bytes2human(
- stats_after.bytes_recv - stats_before.bytes_recv) + '/s',
- ))
- print_line(templ % (
- "pkts-sent",
- stats_after.packets_sent,
- stats_after.packets_sent - stats_before.packets_sent,
- ))
- print_line(templ % (
- "pkts-recv",
- stats_after.packets_recv,
- stats_after.packets_recv - stats_before.packets_recv,
- ))
- print_line("")
- win.refresh()
- lineno = 0
-
-
-def main():
- try:
- interval = 0
- while True:
- args = poll(interval)
- refresh_window(*args)
- interval = 1
- except (KeyboardInterrupt, SystemExit):
- pass
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/pidof.py b/python/psutil/examples/pidof.py
deleted file mode 100755
index 8692a3152..000000000
--- a/python/psutil/examples/pidof.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2009, Giampaolo Rodola', karthikrev. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-"""
-A clone of 'pidof' cmdline utility.
-$ pidof python
-1140 1138 1136 1134 1133 1129 1127 1125 1121 1120 1119
-"""
-
-from __future__ import print_function
-import psutil
-import sys
-
-
-def pidof(pgname):
- pids = []
- for proc in psutil.process_iter():
- # search for matches in the process name and cmdline
- try:
- name = proc.name()
- except psutil.Error:
- pass
- else:
- if name == pgname:
- pids.append(str(proc.pid))
- continue
-
- try:
- cmdline = proc.cmdline()
- except psutil.Error:
- pass
- else:
- if cmdline and cmdline[0] == pgname:
- pids.append(str(proc.pid))
-
- return pids
-
-
-def main():
- if len(sys.argv) != 2:
- sys.exit('usage: %s pgname' % __file__)
- else:
- pgname = sys.argv[1]
- pids = pidof(pgname)
- if pids:
- print(" ".join(pids))
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/pmap.py b/python/psutil/examples/pmap.py
deleted file mode 100755
index 7593777ae..000000000
--- a/python/psutil/examples/pmap.py
+++ /dev/null
@@ -1,57 +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 'pmap' utility on Linux, 'vmmap' on OSX and 'procstat -v' on BSD.
-Report memory map of a process.
-
-$ python examples/pmap.py 32402
-pid=32402, name=hg
-Address RSS Mode Mapping
-0000000000400000 1200K r-xp /usr/bin/python2.7
-0000000000838000 4K r--p /usr/bin/python2.7
-0000000000839000 304K rw-p /usr/bin/python2.7
-00000000008ae000 68K rw-p [anon]
-000000000275e000 5396K rw-p [heap]
-00002b29bb1e0000 124K r-xp /lib/x86_64-linux-gnu/ld-2.17.so
-00002b29bb203000 8K rw-p [anon]
-00002b29bb220000 528K rw-p [anon]
-00002b29bb2d8000 768K rw-p [anon]
-00002b29bb402000 4K r--p /lib/x86_64-linux-gnu/ld-2.17.so
-00002b29bb403000 8K rw-p /lib/x86_64-linux-gnu/ld-2.17.so
-00002b29bb405000 60K r-xp /lib/x86_64-linux-gnu/libpthread-2.17.so
-00002b29bb41d000 0K ---p /lib/x86_64-linux-gnu/libpthread-2.17.so
-00007fff94be6000 48K rw-p [stack]
-00007fff94dd1000 4K r-xp [vdso]
-ffffffffff600000 0K r-xp [vsyscall]
-...
-"""
-
-import sys
-
-import psutil
-
-
-def main():
- if len(sys.argv) != 2:
- sys.exit('usage: pmap <pid>')
- p = psutil.Process(int(sys.argv[1]))
- print("pid=%s, name=%s" % (p.pid, p.name()))
- templ = "%-16s %10s %-7s %s"
- print(templ % ("Address", "RSS", "Mode", "Mapping"))
- total_rss = 0
- for m in p.memory_maps(grouped=False):
- total_rss += m.rss
- print(templ % (
- m.addr.split('-')[0].zfill(16),
- str(m.rss / 1024) + 'K',
- m.perms,
- m.path))
- print("-" * 33)
- print(templ % ("Total", str(total_rss / 1024) + 'K', '', ''))
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/process_detail.py b/python/psutil/examples/process_detail.py
deleted file mode 100755
index e20371aef..000000000
--- a/python/psutil/examples/process_detail.py
+++ /dev/null
@@ -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())
diff --git a/python/psutil/examples/ps.py b/python/psutil/examples/ps.py
deleted file mode 100644
index 2b67bd18f..000000000
--- a/python/psutil/examples/ps.py
+++ /dev/null
@@ -1,81 +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 'ps -aux' on UNIX.
-
-$ python examples/ps.py
-...
-"""
-
-import datetime
-import os
-import time
-
-import psutil
-
-
-def main():
- today_day = datetime.date.today()
- templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s %s"
- attrs = ['pid', 'cpu_percent', 'memory_percent', 'name', 'cpu_times',
- 'create_time', 'memory_info']
- if os.name == 'posix':
- attrs.append('uids')
- attrs.append('terminal')
- print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
- "START", "TIME", "COMMAND"))
- for p in psutil.process_iter():
- try:
- pinfo = p.as_dict(attrs, ad_value='')
- except psutil.NoSuchProcess:
- pass
- else:
- if pinfo['create_time']:
- ctime = datetime.datetime.fromtimestamp(pinfo['create_time'])
- if ctime.date() == today_day:
- ctime = ctime.strftime("%H:%M")
- else:
- ctime = ctime.strftime("%b%d")
- else:
- ctime = ''
- cputime = time.strftime("%M:%S",
- time.localtime(sum(pinfo['cpu_times'])))
- try:
- user = p.username()
- except KeyError:
- if os.name == 'posix':
- if pinfo['uids']:
- user = str(pinfo['uids'].real)
- else:
- user = ''
- else:
- raise
- except psutil.Error:
- user = ''
- if os.name == 'nt' and '\\' in user:
- user = user.split('\\')[1]
- vms = pinfo['memory_info'] and \
- int(pinfo['memory_info'].vms / 1024) or '?'
- rss = pinfo['memory_info'] and \
- int(pinfo['memory_info'].rss / 1024) or '?'
- memp = pinfo['memory_percent'] and \
- round(pinfo['memory_percent'], 1) or '?'
- print(templ % (
- user[:10],
- pinfo['pid'],
- pinfo['cpu_percent'],
- memp,
- vms,
- rss,
- pinfo.get('terminal', '') or '?',
- ctime,
- cputime,
- pinfo['name'].strip() or '?'))
-
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/pstree.py b/python/psutil/examples/pstree.py
deleted file mode 100644
index 1bf8c9c04..000000000
--- a/python/psutil/examples/pstree.py
+++ /dev/null
@@ -1,71 +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.
-
-"""
-Similar to 'ps aux --forest' on Linux, prints the process list
-as a tree structure.
-
-$ python examples/pstree.py
-0 ?
-|- 1 init
-| |- 289 cgmanager
-| |- 616 upstart-socket-bridge
-| |- 628 rpcbind
-| |- 892 upstart-file-bridge
-| |- 907 dbus-daemon
-| |- 978 avahi-daemon
-| | `_ 979 avahi-daemon
-| |- 987 NetworkManager
-| | |- 2242 dnsmasq
-| | `_ 10699 dhclient
-| |- 993 polkitd
-| |- 1061 getty
-| |- 1066 su
-| | `_ 1190 salt-minion...
-...
-"""
-
-from __future__ import print_function
-import collections
-import sys
-
-import psutil
-
-
-def print_tree(parent, tree, indent=''):
- try:
- name = psutil.Process(parent).name()
- except psutil.Error:
- name = "?"
- print(parent, name)
- if parent not in tree:
- return
- children = tree[parent][:-1]
- for child in children:
- sys.stdout.write(indent + "|- ")
- print_tree(child, tree, indent + "| ")
- child = tree[parent][-1]
- sys.stdout.write(indent + "`_ ")
- print_tree(child, tree, indent + " ")
-
-
-def main():
- # construct a dict where 'values' are all the processes
- # having 'key' as their parent
- tree = collections.defaultdict(list)
- for p in psutil.process_iter():
- try:
- tree[p.ppid()].append(p.pid)
- except (psutil.NoSuchProcess, psutil.ZombieProcess):
- pass
- # on systems supporting PID 0, PID 0's parent is usually 0
- if 0 in tree and 0 in tree[0]:
- tree[0].remove(0)
- print_tree(min(tree), tree)
-
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/top.py b/python/psutil/examples/top.py
deleted file mode 100755
index 30df417f5..000000000
--- a/python/psutil/examples/top.py
+++ /dev/null
@@ -1,233 +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 top / htop.
-
-Author: Giampaolo Rodola' <g.rodola@gmail.com>
-
-$ python examples/top.py
- CPU0 [| ] 4.9%
- CPU1 [||| ] 7.8%
- CPU2 [ ] 2.0%
- CPU3 [||||| ] 13.9%
- Mem [||||||||||||||||||| ] 49.8% 4920M/9888M
- Swap [ ] 0.0% 0M/0M
- Processes: 287 (running=1 sleeping=286)
- Load average: 0.34 0.54 0.46 Uptime: 3 days, 10:16:37
-
-PID USER NI VIRT RES CPU% MEM% TIME+ NAME
-------------------------------------------------------------
-989 giampaol 0 66M 12M 7.4 0.1 0:00.61 python
-2083 root 0 506M 159M 6.5 1.6 0:29.26 Xorg
-4503 giampaol 0 599M 25M 6.5 0.3 3:32.60 gnome-terminal
-3868 giampaol 0 358M 8M 2.8 0.1 23:12.60 pulseaudio
-3936 giampaol 0 1G 111M 2.8 1.1 33:41.67 compiz
-4401 giampaol 0 536M 141M 2.8 1.4 35:42.73 skype
-4047 giampaol 0 743M 76M 1.8 0.8 42:03.33 unity-panel-service
-13155 giampaol 0 1G 280M 1.8 2.8 41:57.34 chrome
-10 root 0 0B 0B 0.9 0.0 4:01.81 rcu_sched
-339 giampaol 0 1G 113M 0.9 1.1 8:15.73 chrome
-...
-"""
-
-from datetime import datetime, timedelta
-import atexit
-import os
-import time
-import sys
-try:
- import curses
-except ImportError:
- sys.exit('platform not supported')
-
-import psutil
-
-
-# --- curses stuff
-def tear_down():
- win.keypad(0)
- curses.nocbreak()
- curses.echo()
- curses.endwin()
-
-win = curses.initscr()
-atexit.register(tear_down)
-curses.endwin()
-lineno = 0
-
-
-def print_line(line, highlight=False):
- """A thin wrapper around curses's addstr()."""
- global lineno
- try:
- if highlight:
- line += " " * (win.getmaxyx()[1] - len(line))
- win.addstr(lineno, 0, line, curses.A_REVERSE)
- else:
- win.addstr(lineno, 0, line, 0)
- except curses.error:
- lineno = 0
- win.refresh()
- raise
- else:
- lineno += 1
-# --- /curses stuff
-
-
-def bytes2human(n):
- """
- >>> bytes2human(10000)
- '9K'
- >>> bytes2human(100001221)
- '95M'
- """
- 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 = int(float(n) / prefix[s])
- return '%s%s' % (value, s)
- return "%sB" % n
-
-
-def poll(interval):
- # sleep some time
- time.sleep(interval)
- procs = []
- procs_status = {}
- for p in psutil.process_iter():
- try:
- p.dict = p.as_dict(['username', 'nice', 'memory_info',
- 'memory_percent', 'cpu_percent',
- 'cpu_times', 'name', 'status'])
- try:
- procs_status[p.dict['status']] += 1
- except KeyError:
- procs_status[p.dict['status']] = 1
- except psutil.NoSuchProcess:
- pass
- else:
- procs.append(p)
-
- # return processes sorted by CPU percent usage
- processes = sorted(procs, key=lambda p: p.dict['cpu_percent'],
- reverse=True)
- return (processes, procs_status)
-
-
-def print_header(procs_status, num_procs):
- """Print system-related info, above the process list."""
-
- def get_dashes(perc):
- dashes = "|" * int((float(perc) / 10 * 4))
- empty_dashes = " " * (40 - len(dashes))
- return dashes, empty_dashes
-
- # cpu usage
- percs = psutil.cpu_percent(interval=0, percpu=True)
- for cpu_num, perc in enumerate(percs):
- dashes, empty_dashes = get_dashes(perc)
- print_line(" CPU%-2s [%s%s] %5s%%" % (cpu_num, dashes, empty_dashes,
- perc))
- mem = psutil.virtual_memory()
- dashes, empty_dashes = get_dashes(mem.percent)
- used = mem.total - mem.available
- line = " Mem [%s%s] %5s%% %6s/%s" % (
- dashes, empty_dashes,
- mem.percent,
- str(int(used / 1024 / 1024)) + "M",
- str(int(mem.total / 1024 / 1024)) + "M"
- )
- print_line(line)
-
- # swap usage
- swap = psutil.swap_memory()
- dashes, empty_dashes = get_dashes(swap.percent)
- line = " Swap [%s%s] %5s%% %6s/%s" % (
- dashes, empty_dashes,
- swap.percent,
- str(int(swap.used / 1024 / 1024)) + "M",
- str(int(swap.total / 1024 / 1024)) + "M"
- )
- print_line(line)
-
- # processes number and status
- st = []
- for x, y in procs_status.items():
- if y:
- st.append("%s=%s" % (x, y))
- st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
- print_line(" Processes: %s (%s)" % (num_procs, ' '.join(st)))
- # load average, uptime
- uptime = datetime.utcnow() - datetime.fromtimestamp(psutil.boot_time())
- av1, av2, av3 = os.getloadavg()
- line = " Load average: %.2f %.2f %.2f Uptime: %s" \
- % (av1, av2, av3, str(uptime).split('.')[0])
- print_line(line)
-
-
-def refresh_window(procs, procs_status):
- """Print results on screen by using curses."""
- curses.endwin()
- templ = "%-6s %-8s %4s %5s %5s %6s %4s %9s %2s"
- win.erase()
- header = templ % ("PID", "USER", "NI", "VIRT", "RES", "CPU%", "MEM%",
- "TIME+", "NAME")
- print_header(procs_status, len(procs))
- print_line("")
- print_line(header, highlight=True)
- for p in procs:
- # TIME+ column shows process CPU cumulative time and it
- # is expressed as: "mm:ss.ms"
- if p.dict['cpu_times'] is not None:
- ctime = timedelta(seconds=sum(p.dict['cpu_times']))
- ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60,
- str((ctime.seconds % 60)).zfill(2),
- str(ctime.microseconds)[:2])
- else:
- ctime = ''
- if p.dict['memory_percent'] is not None:
- p.dict['memory_percent'] = round(p.dict['memory_percent'], 1)
- else:
- p.dict['memory_percent'] = ''
- if p.dict['cpu_percent'] is None:
- p.dict['cpu_percent'] = ''
- if p.dict['username']:
- username = p.dict['username'][:8]
- else:
- username = ""
- line = templ % (p.pid,
- username,
- p.dict['nice'],
- bytes2human(getattr(p.dict['memory_info'], 'vms', 0)),
- bytes2human(getattr(p.dict['memory_info'], 'rss', 0)),
- p.dict['cpu_percent'],
- p.dict['memory_percent'],
- ctime,
- p.dict['name'] or '',
- )
- try:
- print_line(line)
- except curses.error:
- break
- win.refresh()
-
-
-def main():
- try:
- interval = 0
- while True:
- args = poll(interval)
- refresh_window(*args)
- interval = 1
- except (KeyboardInterrupt, SystemExit):
- pass
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/examples/who.py b/python/psutil/examples/who.py
deleted file mode 100755
index b382bebfa..000000000
--- a/python/psutil/examples/who.py
+++ /dev/null
@@ -1,33 +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 'who' command; print information about users who are
-currently logged in.
-
-$ python examples/who.py
-giampaolo tty7 2014-02-23 17:25 (:0)
-giampaolo pts/7 2014-02-24 18:25 (:192.168.1.56)
-giampaolo pts/8 2014-02-24 18:25 (:0)
-giampaolo pts/9 2014-02-27 01:32 (:0)
-"""
-
-from datetime import datetime
-
-import psutil
-
-
-def main():
- users = psutil.users()
- for user in users:
- print("%-15s %-15s %s (%s)" % (
- user.name,
- user.terminal or '-',
- datetime.fromtimestamp(user.started).strftime("%Y-%m-%d %H:%M"),
- user.host))
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/make.bat b/python/psutil/make.bat
deleted file mode 100644
index 9c430101d..000000000
--- a/python/psutil/make.bat
+++ /dev/null
@@ -1,201 +0,0 @@
-@echo off
-
-rem ==========================================================================
-rem Shortcuts for various tasks, emulating UNIX "make" on Windows.
-rem It is primarly intended as a shortcut for compiling / installing
-rem psutil ("make.bat build", "make.bat install") and running tests
-rem ("make.bat test").
-rem
-rem This script is modeled after my Windows installation which uses:
-rem - Visual studio 2008 for Python 2.6, 2.7, 3.2
-rem - Visual studio 2010 for Python 3.3+
-rem ...therefore it might not work on your Windows installation.
-rem
-rem By default C:\Python27\python.exe is used.
-rem To compile for a specific Python version run:
-rem set PYTHON=C:\Python34\python.exe & make.bat build
-rem
-rem To use a different test script:
-rem set PYTHON=C:\Python34\python.exe & set TSCRIPT=foo.py & make.bat test
-rem ==========================================================================
-
-if "%PYTHON%" == "" (
- set PYTHON=C:\Python27\python.exe
-)
-if "%TSCRIPT%" == "" (
- set TSCRIPT=test\test_psutil.py
-)
-
-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.
-set HOME=%USERPROFILE%
-
-rem ==========================================================================
-
-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
diff --git a/python/psutil/psutil/__init__.py b/python/psutil/psutil/__init__.py
deleted file mode 100644
index 1444425b8..000000000
--- a/python/psutil/psutil/__init__.py
+++ /dev/null
@@ -1,1887 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""psutil is a cross-platform library for retrieving information on
-running processes and system utilization (CPU, memory, disks, network)
-in Python.
-"""
-
-from __future__ import division
-
-import collections
-import errno
-import functools
-import os
-import signal
-import subprocess
-import sys
-import time
-try:
- import pwd
-except ImportError:
- pwd = None
-
-from . import _common
-from ._common import memoize
-from ._compat import callable, long
-from ._compat import PY3 as _PY3
-
-from ._common import (STATUS_RUNNING, # NOQA
- STATUS_SLEEPING,
- STATUS_DISK_SLEEP,
- STATUS_STOPPED,
- STATUS_TRACING_STOP,
- STATUS_ZOMBIE,
- STATUS_DEAD,
- STATUS_WAKING,
- STATUS_LOCKED,
- STATUS_IDLE, # bsd
- STATUS_WAITING) # bsd
-
-from ._common import (CONN_ESTABLISHED,
- CONN_SYN_SENT,
- CONN_SYN_RECV,
- CONN_FIN_WAIT1,
- CONN_FIN_WAIT2,
- CONN_TIME_WAIT,
- CONN_CLOSE,
- CONN_CLOSE_WAIT,
- CONN_LAST_ACK,
- CONN_LISTEN,
- CONN_CLOSING,
- CONN_NONE)
-
-from ._common import (NIC_DUPLEX_FULL, # NOQA
- NIC_DUPLEX_HALF,
- NIC_DUPLEX_UNKNOWN)
-
-if sys.platform.startswith("linux"):
- from . import _pslinux as _psplatform
-
- from ._pslinux import (IOPRIO_CLASS_NONE, # NOQA
- IOPRIO_CLASS_RT,
- IOPRIO_CLASS_BE,
- IOPRIO_CLASS_IDLE)
- # Linux >= 2.6.36
- if _psplatform.HAS_PRLIMIT:
- from ._psutil_linux import (RLIM_INFINITY, # NOQA
- RLIMIT_AS,
- RLIMIT_CORE,
- RLIMIT_CPU,
- RLIMIT_DATA,
- RLIMIT_FSIZE,
- RLIMIT_LOCKS,
- RLIMIT_MEMLOCK,
- RLIMIT_NOFILE,
- RLIMIT_NPROC,
- RLIMIT_RSS,
- RLIMIT_STACK)
- # Kinda ugly but considerably faster than using hasattr() and
- # setattr() against the module object (we are at import time:
- # speed matters).
- from . import _psutil_linux
- try:
- RLIMIT_MSGQUEUE = _psutil_linux.RLIMIT_MSGQUEUE
- except AttributeError:
- pass
- try:
- RLIMIT_NICE = _psutil_linux.RLIMIT_NICE
- except AttributeError:
- pass
- try:
- RLIMIT_RTPRIO = _psutil_linux.RLIMIT_RTPRIO
- except AttributeError:
- pass
- try:
- RLIMIT_RTTIME = _psutil_linux.RLIMIT_RTTIME
- except AttributeError:
- pass
- try:
- RLIMIT_SIGPENDING = _psutil_linux.RLIMIT_SIGPENDING
- except AttributeError:
- pass
- del _psutil_linux
-
-elif sys.platform.startswith("win32"):
- from . import _pswindows as _psplatform
- from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS, # NOQA
- BELOW_NORMAL_PRIORITY_CLASS,
- HIGH_PRIORITY_CLASS,
- IDLE_PRIORITY_CLASS,
- NORMAL_PRIORITY_CLASS,
- REALTIME_PRIORITY_CLASS)
- from ._pswindows import CONN_DELETE_TCB # NOQA
-
-elif sys.platform.startswith("darwin"):
- from . import _psosx as _psplatform
-
-elif sys.platform.startswith("freebsd"):
- from . import _psbsd as _psplatform
-
-elif sys.platform.startswith("sunos"):
- from . import _pssunos as _psplatform
- from ._pssunos import (CONN_IDLE, # NOQA
- CONN_BOUND)
-
-else: # pragma: no cover
- raise NotImplementedError('platform %s is not supported' % sys.platform)
-
-
-__all__ = [
- # exceptions
- "Error", "NoSuchProcess", "ZombieProcess", "AccessDenied",
- "TimeoutExpired",
- # constants
- "version_info", "__version__",
- "STATUS_RUNNING", "STATUS_IDLE", "STATUS_SLEEPING", "STATUS_DISK_SLEEP",
- "STATUS_STOPPED", "STATUS_TRACING_STOP", "STATUS_ZOMBIE", "STATUS_DEAD",
- "STATUS_WAKING", "STATUS_LOCKED", "STATUS_WAITING", "STATUS_LOCKED",
- "CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1",
- "CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
- "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", "CONN_NONE",
- "AF_LINK",
- "NIC_DUPLEX_FULL", "NIC_DUPLEX_HALF", "NIC_DUPLEX_UNKNOWN",
- # classes
- "Process", "Popen",
- # functions
- "pid_exists", "pids", "process_iter", "wait_procs", # proc
- "virtual_memory", "swap_memory", # memory
- "cpu_times", "cpu_percent", "cpu_times_percent", "cpu_count", # cpu
- "net_io_counters", "net_connections", "net_if_addrs", # network
- "net_if_stats",
- "disk_io_counters", "disk_partitions", "disk_usage", # disk
- "users", "boot_time", # others
-]
-__all__.extend(_psplatform.__extra__all__)
-__author__ = "Giampaolo Rodola'"
-__version__ = "3.1.1"
-version_info = tuple([int(num) for num in __version__.split('.')])
-AF_LINK = _psplatform.AF_LINK
-_TOTAL_PHYMEM = None
-_POSIX = os.name == 'posix'
-_WINDOWS = os.name == 'nt'
-_timer = getattr(time, 'monotonic', time.time)
-
-
-# Sanity check in case the user messed up with psutil installation
-# or did something weird with sys.path. In this case we might end
-# up importing a python module using a C extension module which
-# was compiled for a different version of psutil.
-# We want to prevent that by failing sooner rather than later.
-# See: https://github.com/giampaolo/psutil/issues/564
-if (int(__version__.replace('.', '')) !=
- getattr(_psplatform.cext, 'version', None)):
- msg = "version conflict: %r C extension module was built for another " \
- "version of psutil (different than %s)" % (_psplatform.cext.__file__,
- __version__)
- raise ImportError(msg)
-
-
-# =====================================================================
-# --- exceptions
-# =====================================================================
-
-class Error(Exception):
- """Base exception class. All other psutil exceptions inherit
- from this one.
- """
-
- def __init__(self, msg=""):
- self.msg = msg
-
- def __repr__(self):
- ret = "%s.%s %s" % (self.__class__.__module__,
- 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):
- Error.__init__(self, msg)
- self.pid = pid
- self.ppid = ppid
- self.name = name
- self.msg = msg
- if msg is None:
- if name and ppid:
- details = "(pid=%s, name=%s, ppid=%s)" % (
- self.pid, repr(self.name), self.ppid)
- elif name:
- details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
- else:
- details = "(pid=%s)" % self.pid
- self.msg = "process still exists but it's a zombie " + details
-
-
-class AccessDenied(Error):
- """Exception raised when permission to perform an action is denied."""
-
- def __init__(self, pid=None, name=None, msg=None):
- Error.__init__(self, msg)
- self.pid = pid
- self.name = name
- self.msg = msg
- if msg is None:
- if (pid is not None) and (name is not None):
- self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
- elif (pid is not None):
- self.msg = "(pid=%s)" % self.pid
- else:
- self.msg = ""
-
-
-class TimeoutExpired(Error):
- """Raised on Process.wait(timeout) if timeout expires and process
- is still alive.
- """
-
- def __init__(self, seconds, pid=None, name=None):
- Error.__init__(self, "timeout after %s seconds" % seconds)
- self.seconds = seconds
- self.pid = pid
- self.name = name
- if (pid is not None) and (name is not None):
- self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
- elif (pid is not None):
- self.msg += " (pid=%s)" % self.pid
-
-
-# push exception classes into platform specific module namespace
-_psplatform.NoSuchProcess = NoSuchProcess
-_psplatform.ZombieProcess = ZombieProcess
-_psplatform.AccessDenied = AccessDenied
-_psplatform.TimeoutExpired = TimeoutExpired
-
-
-# =====================================================================
-# --- Process class
-# =====================================================================
-
-
-def _assert_pid_not_reused(fun):
- """Decorator which raises NoSuchProcess in case a process is no
- longer running or its PID has been reused.
- """
- @functools.wraps(fun)
- def wrapper(self, *args, **kwargs):
- if not self.is_running():
- raise NoSuchProcess(self.pid, self._name)
- return fun(self, *args, **kwargs)
- return wrapper
-
-
-class Process(object):
- """Represents an OS process with the given PID.
- If PID is omitted current process PID (os.getpid()) is used.
- Raise NoSuchProcess if PID does not exist.
-
- Note that most of the methods of this class do not make sure
- the PID of the process being queried has been reused over time.
- That means you might end up retrieving an information referring
- to another process in case the original one this instance
- refers to is gone in the meantime.
-
- The only exceptions for which process identity is pre-emptively
- checked and guaranteed are:
-
- - parent()
- - children()
- - nice() (set)
- - ionice() (set)
- - rlimit() (set)
- - cpu_affinity (set)
- - suspend()
- - resume()
- - send_signal()
- - terminate()
- - kill()
-
- To prevent this problem for all other methods you can:
- - use is_running() before querying the process
- - if you're continuously iterating over a set of Process
- instances use process_iter() which pre-emptively checks
- process identity for every yielded instance
- """
-
- def __init__(self, pid=None):
- self._init(pid)
-
- def _init(self, pid, _ignore_nsp=False):
- if pid is None:
- pid = os.getpid()
- else:
- if not _PY3 and not isinstance(pid, (int, long)):
- raise TypeError('pid must be an integer (got %r)' % pid)
- if pid < 0:
- raise ValueError('pid must be a positive integer (got %s)'
- % pid)
- self._pid = pid
- self._name = None
- self._exe = None
- self._create_time = None
- self._gone = False
- self._hash = None
- # used for caching on Windows only (on POSIX ppid may change)
- self._ppid = None
- # platform-specific modules define an _psplatform.Process
- # implementation class
- self._proc = _psplatform.Process(pid)
- self._last_sys_cpu_times = None
- self._last_proc_cpu_times = None
- # cache creation time for later use in is_running() method
- try:
- self.create_time()
- except AccessDenied:
- # we should never get here as AFAIK we're able to get
- # process creation time on all platforms even as a
- # limited user
- pass
- except ZombieProcess:
- # Let's consider a zombie process as legitimate as
- # tehcnically it's still alive (it can be queried,
- # although not always, and it's returned by pids()).
- pass
- except NoSuchProcess:
- if not _ignore_nsp:
- msg = 'no process found with pid %s' % pid
- raise NoSuchProcess(pid, None, msg)
- else:
- self._gone = True
- # This pair is supposed to indentify a Process instance
- # univocally over time (the PID alone is not enough as
- # it might refer to a process whose PID has been reused).
- # This will be used later in __eq__() and is_running().
- self._ident = (self.pid, self._create_time)
-
- def __str__(self):
- try:
- pid = self.pid
- name = repr(self.name())
- except ZombieProcess:
- details = "(pid=%s (zombie))" % self.pid
- except NoSuchProcess:
- details = "(pid=%s (terminated))" % self.pid
- except AccessDenied:
- details = "(pid=%s)" % (self.pid)
- else:
- details = "(pid=%s, name=%s)" % (pid, name)
- return "%s.%s%s" % (self.__class__.__module__,
- self.__class__.__name__, details)
-
- def __repr__(self):
- return "<%s at %s>" % (self.__str__(), id(self))
-
- def __eq__(self, other):
- # Test for equality with another Process object based
- # on PID and creation time.
- if not isinstance(other, Process):
- return NotImplemented
- return self._ident == other._ident
-
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- if self._hash is None:
- self._hash = hash(self._ident)
- return self._hash
-
- # --- utility methods
-
- def as_dict(self, attrs=None, ad_value=None):
- """Utility method returning process information as a
- hashable dictionary.
-
- If 'attrs' is specified it must be a list of strings
- reflecting available Process class' attribute names
- (e.g. ['cpu_times', 'name']) else all public (read
- only) attributes are assumed.
-
- 'ad_value' is the value which gets assigned in case
- AccessDenied or ZombieProcess exception is raised when
- retrieving that particular process information.
- """
- excluded_names = set(
- ['send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
- 'is_running', 'as_dict', 'parent', 'children', 'rlimit'])
- retdict = dict()
- ls = set(attrs or [x for x in dir(self)])
- for name in ls:
- if name.startswith('_'):
- continue
- if name in excluded_names:
- continue
- try:
- attr = getattr(self, name)
- if callable(attr):
- ret = attr()
- else:
- ret = attr
- except (AccessDenied, ZombieProcess):
- ret = ad_value
- except NotImplementedError:
- # in case of not implemented functionality (may happen
- # on old or exotic systems) we want to crash only if
- # the user explicitly asked for that particular attr
- if attrs:
- raise
- continue
- retdict[name] = ret
- return retdict
-
- def parent(self):
- """Return the parent process as a Process object pre-emptively
- checking whether PID has been reused.
- If no parent is known return None.
- """
- ppid = self.ppid()
- if ppid is not None:
- ctime = self.create_time()
- try:
- parent = Process(ppid)
- if parent.create_time() <= ctime:
- return parent
- # ...else ppid has been reused by another process
- except NoSuchProcess:
- pass
-
- def is_running(self):
- """Return whether this process is running.
- It also checks if PID has been reused by another process in
- which case return False.
- """
- if self._gone:
- return False
- try:
- # Checking if PID is alive is not enough as the PID might
- # have been reused by another process: we also want to
- # check process identity.
- # Process identity / uniqueness over time is greanted by
- # (PID + creation time) and that is verified in __eq__.
- return self == Process(self.pid)
- except NoSuchProcess:
- self._gone = True
- return False
-
- # --- actual API
-
- @property
- def pid(self):
- """The process PID."""
- return self._pid
-
- def ppid(self):
- """The process parent PID.
- On Windows the return value is cached after first call.
- """
- # On POSIX we don't want to cache the ppid as it may unexpectedly
- # change to 1 (init) in case this process turns into a zombie:
- # https://github.com/giampaolo/psutil/issues/321
- # http://stackoverflow.com/questions/356722/
-
- # XXX should we check creation time here rather than in
- # Process.parent()?
- if _POSIX:
- return self._proc.ppid()
- else:
- self._ppid = self._ppid or self._proc.ppid()
- return self._ppid
-
- def name(self):
- """The process name. The return value is cached after first call."""
- if self._name is None:
- name = self._proc.name()
- if _POSIX and len(name) >= 15:
- # On UNIX the name gets truncated to the first 15 characters.
- # If it matches the first part of the cmdline we return that
- # one instead because it's usually more explicative.
- # Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
- try:
- cmdline = self.cmdline()
- except AccessDenied:
- pass
- else:
- if cmdline:
- extended_name = os.path.basename(cmdline[0])
- if extended_name.startswith(name):
- name = extended_name
- self._proc._name = name
- self._name = name
- return self._name
-
- def exe(self):
- """The process executable as an absolute path.
- May also be an empty string.
- The return value is cached after first call.
- """
- def guess_it(fallback):
- # try to guess exe from cmdline[0] in absence of a native
- # exe representation
- cmdline = self.cmdline()
- if cmdline and hasattr(os, 'access') and hasattr(os, 'X_OK'):
- exe = cmdline[0] # the possible exe
- # Attempt to guess only in case of an absolute path.
- # It is not safe otherwise as the process might have
- # changed cwd.
- if (os.path.isabs(exe) and
- os.path.isfile(exe) and
- os.access(exe, os.X_OK)):
- return exe
- if isinstance(fallback, AccessDenied):
- raise fallback
- return fallback
-
- if self._exe is None:
- try:
- exe = self._proc.exe()
- except AccessDenied as err:
- return guess_it(fallback=err)
- else:
- if not exe:
- # underlying implementation can legitimately return an
- # empty string; if that's the case we don't want to
- # raise AD while guessing from the cmdline
- try:
- exe = guess_it(fallback=exe)
- except AccessDenied:
- pass
- self._exe = exe
- return self._exe
-
- def cmdline(self):
- """The command line this process has been called with."""
- return self._proc.cmdline()
-
- def status(self):
- """The process current status as a STATUS_* constant."""
- try:
- return self._proc.status()
- except ZombieProcess:
- return STATUS_ZOMBIE
-
- def username(self):
- """The name of the user that owns the process.
- On UNIX this is calculated by using *real* process uid.
- """
- if _POSIX:
- if pwd is None:
- # might happen if python was installed from sources
- raise ImportError(
- "requires pwd module shipped with standard python")
- real_uid = self.uids().real
- try:
- return pwd.getpwuid(real_uid).pw_name
- except KeyError:
- # the uid can't be resolved by the system
- return str(real_uid)
- else:
- return self._proc.username()
-
- def create_time(self):
- """The process creation time as a floating point number
- expressed in seconds since the epoch, in UTC.
- The return value is cached after first call.
- """
- if self._create_time is None:
- self._create_time = self._proc.create_time()
- return self._create_time
-
- def cwd(self):
- """Process current working directory as an absolute path."""
- return self._proc.cwd()
-
- def nice(self, value=None):
- """Get or set process niceness (priority)."""
- if value is None:
- return self._proc.nice_get()
- else:
- if not self.is_running():
- raise NoSuchProcess(self.pid, self._name)
- self._proc.nice_set(value)
-
- if _POSIX:
-
- def uids(self):
- """Return process UIDs as a (real, effective, saved)
- namedtuple.
- """
- return self._proc.uids()
-
- def gids(self):
- """Return process GIDs as a (real, effective, saved)
- namedtuple.
- """
- return self._proc.gids()
-
- def terminal(self):
- """The terminal associated with this process, if any,
- else None.
- """
- return self._proc.terminal()
-
- def num_fds(self):
- """Return the number of file descriptors opened by this
- process (POSIX only).
- """
- return self._proc.num_fds()
-
- # Linux, BSD and Windows only
- if hasattr(_psplatform.Process, "io_counters"):
-
- def io_counters(self):
- """Return process I/O statistics as a
- (read_count, write_count, read_bytes, write_bytes)
- namedtuple.
- Those are the number of read/write calls performed and the
- amount of bytes read and written by the process.
- """
- return self._proc.io_counters()
-
- # Linux and Windows >= Vista only
- if hasattr(_psplatform.Process, "ionice_get"):
-
- def ionice(self, ioclass=None, value=None):
- """Get or set process I/O niceness (priority).
-
- On Linux 'ioclass' is one of the IOPRIO_CLASS_* constants.
- 'value' is a number which goes from 0 to 7. The higher the
- value, the lower the I/O priority of the process.
-
- On Windows only 'ioclass' is used and it can be set to 2
- (normal), 1 (low) or 0 (very low).
-
- Available on Linux and Windows > Vista only.
- """
- if ioclass is None:
- if value is not None:
- raise ValueError("'ioclass' argument must be specified")
- return self._proc.ionice_get()
- else:
- return self._proc.ionice_set(ioclass, value)
-
- # Linux only
- if hasattr(_psplatform.Process, "rlimit"):
-
- def rlimit(self, resource, limits=None):
- """Get or set process resource limits as a (soft, hard)
- tuple.
-
- 'resource' is one of the RLIMIT_* constants.
- 'limits' is supposed to be a (soft, hard) tuple.
-
- See "man prlimit" for further info.
- Available on Linux only.
- """
- if limits is None:
- return self._proc.rlimit(resource)
- else:
- return self._proc.rlimit(resource, limits)
-
- # Windows, Linux and BSD only
- if hasattr(_psplatform.Process, "cpu_affinity_get"):
-
- def cpu_affinity(self, cpus=None):
- """Get or set process CPU affinity.
- If specified 'cpus' must be a list of CPUs for which you
- want to set the affinity (e.g. [0, 1]).
- (Windows, Linux and BSD only).
- """
- # Automatically remove duplicates both on get and
- # set (for get it's not really necessary, it's
- # just for extra safety).
- if cpus is None:
- return list(set(self._proc.cpu_affinity_get()))
- else:
- self._proc.cpu_affinity_set(list(set(cpus)))
-
- if _WINDOWS:
-
- def num_handles(self):
- """Return the number of handles opened by this process
- (Windows only).
- """
- return self._proc.num_handles()
-
- def num_ctx_switches(self):
- """Return the number of voluntary and involuntary context
- switches performed by this process.
- """
- return self._proc.num_ctx_switches()
-
- def num_threads(self):
- """Return the number of threads used by this process."""
- return self._proc.num_threads()
-
- def threads(self):
- """Return threads opened by process as a list of
- (id, user_time, system_time) namedtuples representing
- thread id and thread CPU times (user/system).
- """
- return self._proc.threads()
-
- @_assert_pid_not_reused
- def children(self, recursive=False):
- """Return the children of this process as a list of Process
- instances, pre-emptively checking whether PID has been reused.
- If recursive is True return all the parent descendants.
-
- Example (A == this process):
-
- A ─┐
- │
- ├─ B (child) ─┐
- │ └─ X (grandchild) ─┐
- │ └─ Y (great grandchild)
- ├─ C (child)
- └─ D (child)
-
- >>> import psutil
- >>> p = psutil.Process()
- >>> p.children()
- B, C, D
- >>> p.children(recursive=True)
- B, X, Y, C, D
-
- Note that in the example above if process X disappears
- process Y won't be listed as the reference to process A
- is lost.
- """
- if hasattr(_psplatform, 'ppid_map'):
- # Windows only: obtain a {pid:ppid, ...} dict for all running
- # processes in one shot (faster).
- ppid_map = _psplatform.ppid_map()
- else:
- ppid_map = None
-
- ret = []
- if not recursive:
- if ppid_map is None:
- # 'slow' version, common to all platforms except Windows
- for p in process_iter():
- try:
- if p.ppid() == self.pid:
- # if child happens to be older than its parent
- # (self) it means child's PID has been reused
- if self.create_time() <= p.create_time():
- ret.append(p)
- except (NoSuchProcess, ZombieProcess):
- pass
- else:
- # Windows only (faster)
- for pid, ppid in ppid_map.items():
- if ppid == self.pid:
- try:
- child = Process(pid)
- # if child happens to be older than its parent
- # (self) it means child's PID has been reused
- if self.create_time() <= child.create_time():
- ret.append(child)
- except (NoSuchProcess, ZombieProcess):
- pass
- else:
- # construct a dict where 'values' are all the processes
- # having 'key' as their parent
- table = collections.defaultdict(list)
- if ppid_map is None:
- for p in process_iter():
- try:
- table[p.ppid()].append(p)
- except (NoSuchProcess, ZombieProcess):
- pass
- else:
- for pid, ppid in ppid_map.items():
- try:
- p = Process(pid)
- table[ppid].append(p)
- except (NoSuchProcess, ZombieProcess):
- pass
- # At this point we have a mapping table where table[self.pid]
- # are the current process' children.
- # Below, we look for all descendants recursively, similarly
- # to a recursive function call.
- checkpids = [self.pid]
- for pid in checkpids:
- for child in table[pid]:
- try:
- # if child happens to be older than its parent
- # (self) it means child's PID has been reused
- intime = self.create_time() <= child.create_time()
- except (NoSuchProcess, ZombieProcess):
- pass
- else:
- if intime:
- ret.append(child)
- if child.pid not in checkpids:
- checkpids.append(child.pid)
- return ret
-
- def cpu_percent(self, interval=None):
- """Return a float representing the current process CPU
- utilization as a percentage.
-
- When interval is 0.0 or None (default) compares process times
- to system CPU times elapsed since last call, returning
- immediately (non-blocking). That means that the first time
- this is called it will return a meaningful 0.0 value.
-
- When interval is > 0.0 compares process times to system CPU
- times elapsed before and after the interval (blocking).
-
- In this case is recommended for accuracy that this function
- be called with at least 0.1 seconds between calls.
-
- Examples:
-
- >>> import psutil
- >>> p = psutil.Process(os.getpid())
- >>> # blocking
- >>> p.cpu_percent(interval=1)
- 2.0
- >>> # non-blocking (percentage since last call)
- >>> p.cpu_percent(interval=None)
- 2.9
- >>>
- """
- blocking = interval is not None and interval > 0.0
- num_cpus = cpu_count()
- if _POSIX:
- def timer():
- return _timer() * num_cpus
- else:
- def timer():
- return sum(cpu_times())
- if blocking:
- st1 = timer()
- pt1 = self._proc.cpu_times()
- time.sleep(interval)
- st2 = timer()
- pt2 = self._proc.cpu_times()
- else:
- st1 = self._last_sys_cpu_times
- pt1 = self._last_proc_cpu_times
- st2 = timer()
- pt2 = self._proc.cpu_times()
- if st1 is None or pt1 is None:
- self._last_sys_cpu_times = st2
- self._last_proc_cpu_times = pt2
- return 0.0
-
- delta_proc = (pt2.user - pt1.user) + (pt2.system - pt1.system)
- delta_time = st2 - st1
- # reset values for next call in case of interval == None
- self._last_sys_cpu_times = st2
- self._last_proc_cpu_times = pt2
-
- try:
- # The utilization split between all CPUs.
- # Note: a percentage > 100 is legitimate as it can result
- # from a process with multiple threads running on different
- # CPU cores, see:
- # http://stackoverflow.com/questions/1032357
- # https://github.com/giampaolo/psutil/issues/474
- overall_percent = ((delta_proc / delta_time) * 100) * num_cpus
- except ZeroDivisionError:
- # interval was too low
- return 0.0
- else:
- return round(overall_percent, 1)
-
- def cpu_times(self):
- """Return a (user, system) namedtuple representing the
- accumulated process time, in seconds.
- This is the same as os.times() but per-process.
- """
- return self._proc.cpu_times()
-
- def memory_info(self):
- """Return a tuple representing RSS (Resident Set Size) and VMS
- (Virtual Memory Size) in bytes.
-
- On UNIX RSS and VMS are the same values shown by 'ps'.
-
- On Windows RSS and VMS refer to "Mem Usage" and "VM Size"
- columns of taskmgr.exe.
- """
- return self._proc.memory_info()
-
- def memory_info_ex(self):
- """Return a namedtuple with variable fields depending on the
- platform representing extended memory information about
- this process. All numbers are expressed in bytes.
- """
- return self._proc.memory_info_ex()
-
- def memory_percent(self):
- """Compare physical system memory to process resident memory
- (RSS) and calculate process memory utilization as a percentage.
- """
- rss = self._proc.memory_info()[0]
- # use cached value if available
- total_phymem = _TOTAL_PHYMEM or virtual_memory().total
- try:
- return (rss / float(total_phymem)) * 100
- except ZeroDivisionError:
- return 0.0
-
- def memory_maps(self, grouped=True):
- """Return process' mapped memory regions as a list of namedtuples
- whose fields are variable depending on the platform.
-
- If 'grouped' is True the mapped regions with the same 'path'
- are grouped together and the different memory fields are summed.
-
- If 'grouped' is False every mapped region is shown as a single
- entity and the namedtuple will also include the mapped region's
- address space ('addr') and permission set ('perms').
- """
- it = self._proc.memory_maps()
- if grouped:
- d = {}
- for tupl in it:
- path = tupl[2]
- nums = tupl[3:]
- try:
- d[path] = map(lambda x, y: x + y, d[path], nums)
- except KeyError:
- d[path] = nums
- nt = _psplatform.pmmap_grouped
- return [nt(path, *d[path]) for path in d] # NOQA
- else:
- nt = _psplatform.pmmap_ext
- return [nt(*x) for x in it]
-
- def open_files(self):
- """Return files opened by process as a list of
- (path, fd) namedtuples including the absolute file name
- and file descriptor number.
- """
- return self._proc.open_files()
-
- def connections(self, kind='inet'):
- """Return connections opened by process as a list of
- (fd, family, type, laddr, raddr, status) namedtuples.
- The 'kind' parameter filters for connections that match the
- following criteria:
-
- Kind Value Connections using
- inet IPv4 and IPv6
- inet4 IPv4
- inet6 IPv6
- tcp TCP
- tcp4 TCP over IPv4
- tcp6 TCP over IPv6
- udp UDP
- udp4 UDP over IPv4
- udp6 UDP over IPv6
- unix UNIX socket (both UDP and TCP protocols)
- all the sum of all the possible families and protocols
- """
- return self._proc.connections(kind)
-
- if _POSIX:
- def _send_signal(self, sig):
- if self.pid == 0:
- # see "man 2 kill"
- raise ValueError(
- "preventing sending signal to process with PID 0 as it "
- "would affect every process in the process group of the "
- "calling process (os.getpid()) instead of PID 0")
- try:
- os.kill(self.pid, sig)
- except OSError as err:
- if err.errno == errno.ESRCH:
- self._gone = True
- raise NoSuchProcess(self.pid, self._name)
- if err.errno == errno.EPERM:
- raise AccessDenied(self.pid, self._name)
- raise
-
- @_assert_pid_not_reused
- def send_signal(self, sig):
- """Send a signal to process pre-emptively checking whether
- PID has been reused (see signal module constants) .
- On Windows only SIGTERM is valid and is treated as an alias
- for kill().
- """
- if _POSIX:
- self._send_signal(sig)
- else:
- if sig == signal.SIGTERM:
- self._proc.kill()
- else:
- raise ValueError("only SIGTERM is supported on Windows")
-
- @_assert_pid_not_reused
- def suspend(self):
- """Suspend process execution with SIGSTOP pre-emptively checking
- whether PID has been reused.
- On Windows this has the effect ot suspending all process threads.
- """
- if _POSIX:
- self._send_signal(signal.SIGSTOP)
- else:
- self._proc.suspend()
-
- @_assert_pid_not_reused
- def resume(self):
- """Resume process execution with SIGCONT pre-emptively checking
- whether PID has been reused.
- On Windows this has the effect of resuming all process threads.
- """
- if _POSIX:
- self._send_signal(signal.SIGCONT)
- else:
- self._proc.resume()
-
- @_assert_pid_not_reused
- def terminate(self):
- """Terminate the process with SIGTERM pre-emptively checking
- whether PID has been reused.
- On Windows this is an alias for kill().
- """
- if _POSIX:
- self._send_signal(signal.SIGTERM)
- else:
- self._proc.kill()
-
- @_assert_pid_not_reused
- def kill(self):
- """Kill the current process with SIGKILL pre-emptively checking
- whether PID has been reused.
- """
- if _POSIX:
- self._send_signal(signal.SIGKILL)
- else:
- self._proc.kill()
-
- def wait(self, timeout=None):
- """Wait for process to terminate and, if process is a children
- of os.getpid(), also return its exit code, else None.
-
- If the process is already terminated immediately return None
- instead of raising NoSuchProcess.
-
- If timeout (in seconds) is specified and process is still alive
- raise TimeoutExpired.
-
- To wait for multiple Process(es) use psutil.wait_procs().
- """
- if timeout is not None and not timeout >= 0:
- raise ValueError("timeout must be a positive integer")
- return self._proc.wait(timeout)
-
-
-# =====================================================================
-# --- Popen class
-# =====================================================================
-
-
-class Popen(Process):
- """A more convenient interface to stdlib subprocess module.
- It starts a sub process and deals with it exactly as when using
- subprocess.Popen class but in addition also provides all the
- properties and methods of psutil.Process class as a unified
- interface:
-
- >>> import psutil
- >>> from subprocess import PIPE
- >>> p = psutil.Popen(["python", "-c", "print 'hi'"], stdout=PIPE)
- >>> p.name()
- 'python'
- >>> p.uids()
- user(real=1000, effective=1000, saved=1000)
- >>> p.username()
- 'giampaolo'
- >>> p.communicate()
- ('hi\n', None)
- >>> p.terminate()
- >>> p.wait(timeout=2)
- 0
- >>>
-
- For method names common to both classes such as kill(), terminate()
- and wait(), psutil.Process implementation takes precedence.
-
- Unlike subprocess.Popen this class pre-emptively checks wheter PID
- has been reused on send_signal(), terminate() and kill() so that
- you don't accidentally terminate another process, fixing
- http://bugs.python.org/issue6973.
-
- For a complete documentation refer to:
- http://docs.python.org/library/subprocess.html
- """
-
- def __init__(self, *args, **kwargs):
- # Explicitly avoid to raise NoSuchProcess in case the process
- # spawned by subprocess.Popen terminates too quickly, see:
- # https://github.com/giampaolo/psutil/issues/193
- self.__subproc = subprocess.Popen(*args, **kwargs)
- self._init(self.__subproc.pid, _ignore_nsp=True)
-
- def __dir__(self):
- return sorted(set(dir(Popen) + dir(subprocess.Popen)))
-
- def __getattribute__(self, name):
- try:
- return object.__getattribute__(self, name)
- except AttributeError:
- try:
- return object.__getattribute__(self.__subproc, name)
- except AttributeError:
- raise AttributeError("%s instance has no attribute '%s'"
- % (self.__class__.__name__, name))
-
- def wait(self, timeout=None):
- if self.__subproc.returncode is not None:
- return self.__subproc.returncode
- ret = super(Popen, self).wait(timeout)
- self.__subproc.returncode = ret
- return ret
-
-
-# =====================================================================
-# --- system processes related functions
-# =====================================================================
-
-
-def pids():
- """Return a list of current running PIDs."""
- return _psplatform.pids()
-
-
-def pid_exists(pid):
- """Return True if given PID exists in the current process list.
- This is faster than doing "pid in psutil.pids()" and
- should be preferred.
- """
- if pid < 0:
- return False
- elif pid == 0 and _POSIX:
- # On POSIX we use os.kill() to determine PID existence.
- # According to "man 2 kill" PID 0 has a special meaning
- # though: it refers to <<every process in the process
- # group of the calling process>> and that is not we want
- # to do here.
- return pid in pids()
- else:
- return _psplatform.pid_exists(pid)
-
-
-_pmap = {}
-
-
-def process_iter():
- """Return a generator yielding a Process instance for all
- running processes.
-
- Every new Process instance is only created once and then cached
- into an internal table which is updated every time this is used.
-
- Cached Process instances are checked for identity so that you're
- safe in case a PID has been reused by another process, in which
- case the cached instance is updated.
-
- The sorting order in which processes are yielded is based on
- their PIDs.
- """
- def add(pid):
- proc = Process(pid)
- _pmap[proc.pid] = proc
- return proc
-
- def remove(pid):
- _pmap.pop(pid, None)
-
- a = set(pids())
- b = set(_pmap.keys())
- new_pids = a - b
- gone_pids = b - a
-
- for pid in gone_pids:
- remove(pid)
- for pid, proc in sorted(list(_pmap.items()) +
- list(dict.fromkeys(new_pids).items())):
- try:
- if proc is None: # new process
- yield add(pid)
- else:
- # use is_running() to check whether PID has been reused by
- # another process in which case yield a new Process instance
- if proc.is_running():
- yield proc
- else:
- yield add(pid)
- except NoSuchProcess:
- remove(pid)
- except AccessDenied:
- # Process creation time can't be determined hence there's
- # no way to tell whether the pid of the cached process
- # has been reused. Just return the cached version.
- yield proc
-
-
-def wait_procs(procs, timeout=None, callback=None):
- """Convenience function which waits for a list of processes to
- terminate.
-
- Return a (gone, alive) tuple indicating which processes
- are gone and which ones are still alive.
-
- The gone ones will have a new 'returncode' attribute indicating
- process exit status (may be None).
-
- 'callback' is a function which gets called every time a process
- terminates (a Process instance is passed as callback argument).
-
- Function will return as soon as all processes terminate or when
- timeout occurs.
-
- Typical use case is:
-
- - send SIGTERM to a list of processes
- - give them some time to terminate
- - send SIGKILL to those ones which are still alive
-
- Example:
-
- >>> def on_terminate(proc):
- ... print("process {} terminated".format(proc))
- ...
- >>> for p in procs:
- ... p.terminate()
- ...
- >>> gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
- >>> for p in alive:
- ... p.kill()
- """
- def check_gone(proc, timeout):
- try:
- returncode = proc.wait(timeout=timeout)
- except TimeoutExpired:
- pass
- else:
- if returncode is not None or not proc.is_running():
- proc.returncode = returncode
- gone.add(proc)
- if callback is not None:
- callback(proc)
-
- if timeout is not None and not timeout >= 0:
- msg = "timeout must be a positive integer, got %s" % timeout
- raise ValueError(msg)
- gone = set()
- alive = set(procs)
- if callback is not None and not callable(callback):
- raise TypeError("callback %r is not a callable" % callable)
- if timeout is not None:
- deadline = _timer() + timeout
-
- while alive:
- if timeout is not None and timeout <= 0:
- break
- for proc in alive:
- # Make sure that every complete iteration (all processes)
- # will last max 1 sec.
- # We do this because we don't want to wait too long on a
- # single process: in case it terminates too late other
- # processes may disappear in the meantime and their PID
- # reused.
- max_timeout = 1.0 / len(alive)
- if timeout is not None:
- timeout = min((deadline - _timer()), max_timeout)
- if timeout <= 0:
- break
- check_gone(proc, timeout)
- else:
- check_gone(proc, max_timeout)
- alive = alive - gone
-
- if alive:
- # Last attempt over processes survived so far.
- # timeout == 0 won't make this function wait any further.
- for proc in alive:
- check_gone(proc, 0)
- alive = alive - gone
-
- return (list(gone), list(alive))
-
-
-# =====================================================================
-# --- CPU related functions
-# =====================================================================
-
-
-@memoize
-def cpu_count(logical=True):
- """Return the number of logical CPUs in the system (same as
- os.cpu_count() in Python 3.4).
-
- If logical is False return the number of physical cores only
- (e.g. hyper thread CPUs are excluded).
-
- Return None if undetermined.
-
- The return value is cached after first call.
- If desired cache can be cleared like this:
-
- >>> psutil.cpu_count.cache_clear()
- """
- if logical:
- return _psplatform.cpu_count_logical()
- else:
- return _psplatform.cpu_count_physical()
-
-
-def cpu_times(percpu=False):
- """Return system-wide CPU times as a namedtuple.
- Every CPU time represents the seconds the CPU has spent in the given mode.
- The namedtuple's fields availability varies depending on the platform:
- - user
- - system
- - idle
- - nice (UNIX)
- - iowait (Linux)
- - irq (Linux, FreeBSD)
- - softirq (Linux)
- - steal (Linux >= 2.6.11)
- - guest (Linux >= 2.6.24)
- - guest_nice (Linux >= 3.2.0)
-
- When percpu is True return a list of namedtuples for each CPU.
- First element of the list refers to first CPU, second element
- to second CPU and so on.
- The order of the list is consistent across calls.
- """
- if not percpu:
- return _psplatform.cpu_times()
- else:
- return _psplatform.per_cpu_times()
-
-
-_last_cpu_times = cpu_times()
-_last_per_cpu_times = cpu_times(percpu=True)
-
-
-def cpu_percent(interval=None, percpu=False):
- """Return a float representing the current system-wide CPU
- utilization as a percentage.
-
- When interval is > 0.0 compares system CPU times elapsed before
- and after the interval (blocking).
-
- When interval is 0.0 or None compares system CPU times elapsed
- since last call or module import, returning immediately (non
- blocking). That means the first time this is called it will
- return a meaningless 0.0 value which you should ignore.
- In this case is recommended for accuracy that this function be
- called with at least 0.1 seconds between calls.
-
- When percpu is True returns a list of floats representing the
- utilization as a percentage for each CPU.
- First element of the list refers to first CPU, second element
- to second CPU and so on.
- The order of the list is consistent across calls.
-
- Examples:
-
- >>> # blocking, system-wide
- >>> psutil.cpu_percent(interval=1)
- 2.0
- >>>
- >>> # blocking, per-cpu
- >>> psutil.cpu_percent(interval=1, percpu=True)
- [2.0, 1.0]
- >>>
- >>> # non-blocking (percentage since last call)
- >>> psutil.cpu_percent(interval=None)
- 2.9
- >>>
- """
- global _last_cpu_times
- global _last_per_cpu_times
- blocking = interval is not None and interval > 0.0
-
- def calculate(t1, t2):
- t1_all = sum(t1)
- t1_busy = t1_all - t1.idle
-
- t2_all = sum(t2)
- t2_busy = t2_all - t2.idle
-
- # this usually indicates a float precision issue
- if t2_busy <= t1_busy:
- return 0.0
-
- busy_delta = t2_busy - t1_busy
- all_delta = t2_all - t1_all
- busy_perc = (busy_delta / all_delta) * 100
- return round(busy_perc, 1)
-
- # system-wide usage
- if not percpu:
- if blocking:
- t1 = cpu_times()
- time.sleep(interval)
- else:
- t1 = _last_cpu_times
- _last_cpu_times = cpu_times()
- return calculate(t1, _last_cpu_times)
- # per-cpu usage
- else:
- ret = []
- if blocking:
- tot1 = cpu_times(percpu=True)
- time.sleep(interval)
- else:
- tot1 = _last_per_cpu_times
- _last_per_cpu_times = cpu_times(percpu=True)
- for t1, t2 in zip(tot1, _last_per_cpu_times):
- ret.append(calculate(t1, t2))
- return ret
-
-
-# Use separate global vars for cpu_times_percent() so that it's
-# independent from cpu_percent() and they can both be used within
-# the same program.
-_last_cpu_times_2 = _last_cpu_times
-_last_per_cpu_times_2 = _last_per_cpu_times
-
-
-def cpu_times_percent(interval=None, percpu=False):
- """Same as cpu_percent() but provides utilization percentages
- for each specific CPU time as is returned by cpu_times().
- For instance, on Linux we'll get:
-
- >>> cpu_times_percent()
- cpupercent(user=4.8, nice=0.0, system=4.8, idle=90.5, iowait=0.0,
- irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
- >>>
-
- interval and percpu arguments have the same meaning as in
- cpu_percent().
- """
- global _last_cpu_times_2
- global _last_per_cpu_times_2
- blocking = interval is not None and interval > 0.0
-
- def calculate(t1, t2):
- nums = []
- all_delta = sum(t2) - sum(t1)
- for field in t1._fields:
- field_delta = getattr(t2, field) - getattr(t1, field)
- try:
- field_perc = (100 * field_delta) / all_delta
- except ZeroDivisionError:
- field_perc = 0.0
- field_perc = round(field_perc, 1)
- # CPU times are always supposed to increase over time
- # or at least remain the same and that's because time
- # cannot go backwards.
- # Surprisingly sometimes this might not be the case (at
- # least on Windows and Linux), see:
- # https://github.com/giampaolo/psutil/issues/392
- # https://github.com/giampaolo/psutil/issues/645
- # I really don't know what to do about that except
- # forcing the value to 0 or 100.
- if field_perc > 100.0:
- field_perc = 100.0
- # `<=` because `-0.0 == 0.0` evaluates to True
- elif field_perc <= 0.0:
- field_perc = 0.0
- nums.append(field_perc)
- return _psplatform.scputimes(*nums)
-
- # system-wide usage
- if not percpu:
- if blocking:
- t1 = cpu_times()
- time.sleep(interval)
- else:
- t1 = _last_cpu_times_2
- _last_cpu_times_2 = cpu_times()
- return calculate(t1, _last_cpu_times_2)
- # per-cpu usage
- else:
- ret = []
- if blocking:
- tot1 = cpu_times(percpu=True)
- time.sleep(interval)
- else:
- tot1 = _last_per_cpu_times_2
- _last_per_cpu_times_2 = cpu_times(percpu=True)
- for t1, t2 in zip(tot1, _last_per_cpu_times_2):
- ret.append(calculate(t1, t2))
- return ret
-
-
-# =====================================================================
-# --- system memory related functions
-# =====================================================================
-
-
-def virtual_memory():
- """Return statistics about system memory usage as a namedtuple
- including the following fields, expressed in bytes:
-
- - total:
- total physical memory available.
-
- - available:
- the actual amount of available memory that can be given
- instantly to processes that request more memory in bytes; this
- is calculated by summing different memory values depending on
- the platform (e.g. free + buffers + cached on Linux) and it is
- supposed to be used to monitor actual memory usage in a cross
- platform fashion.
-
- - percent:
- the percentage usage calculated as (total - available) / total * 100
-
- - used:
- memory used, calculated differently depending on the platform and
- designed for informational purposes only:
- OSX: active + inactive + wired
- BSD: active + wired + cached
- LINUX: total - free
-
- - free:
- memory not being used at all (zeroed) that is readily available;
- note that this doesn't reflect the actual memory available
- (use 'available' instead)
-
- Platform-specific fields:
-
- - active (UNIX):
- memory currently in use or very recently used, and so it is in RAM.
-
- - inactive (UNIX):
- memory that is marked as not used.
-
- - buffers (BSD, Linux):
- cache for things like file system metadata.
-
- - cached (BSD, OSX):
- cache for various things.
-
- - wired (OSX, BSD):
- memory that is marked to always stay in RAM. It is never moved to disk.
-
- - shared (BSD):
- memory that may be simultaneously accessed by multiple processes.
-
- The sum of 'used' and 'available' does not necessarily equal total.
- On Windows 'available' and 'free' are the same.
- """
- global _TOTAL_PHYMEM
- ret = _psplatform.virtual_memory()
- # cached for later use in Process.memory_percent()
- _TOTAL_PHYMEM = ret.total
- return ret
-
-
-def swap_memory():
- """Return system swap memory statistics as a namedtuple including
- the following fields:
-
- - total: total swap memory in bytes
- - used: used swap memory in bytes
- - free: free swap memory in bytes
- - percent: the percentage usage
- - sin: no. of bytes the system has swapped in from disk (cumulative)
- - sout: no. of bytes the system has swapped out from disk (cumulative)
-
- 'sin' and 'sout' on Windows are meaningless and always set to 0.
- """
- return _psplatform.swap_memory()
-
-
-# =====================================================================
-# --- disks/paritions related functions
-# =====================================================================
-
-
-def disk_usage(path):
- """Return disk usage statistics about the given path as a namedtuple
- including total, used and free space expressed in bytes plus the
- percentage usage.
- """
- return _psplatform.disk_usage(path)
-
-
-def disk_partitions(all=False):
- """Return mounted partitions as a list of
- (device, mountpoint, fstype, opts) namedtuple.
- 'opts' field is a raw string separated by commas indicating mount
- options which may vary depending on the platform.
-
- If "all" parameter is False return physical devices only and ignore
- all others.
- """
- return _psplatform.disk_partitions(all)
-
-
-def disk_io_counters(perdisk=False):
- """Return system disk I/O statistics as a namedtuple including
- the following fields:
-
- - read_count: number of reads
- - write_count: number of writes
- - read_bytes: number of bytes read
- - write_bytes: number of bytes written
- - read_time: time spent reading from disk (in milliseconds)
- - write_time: time spent writing to disk (in milliseconds)
-
- If perdisk is True return the same information for every
- physical disk installed on the system as a dictionary
- with partition names as the keys and the namedtuple
- described above as the values.
-
- On recent Windows versions 'diskperf -y' command may need to be
- executed first otherwise this function won't find any disk.
- """
- rawdict = _psplatform.disk_io_counters()
- if not rawdict:
- raise RuntimeError("couldn't find any physical disk")
- if perdisk:
- for disk, fields in rawdict.items():
- rawdict[disk] = _common.sdiskio(*fields)
- return rawdict
- else:
- return _common.sdiskio(*[sum(x) for x in zip(*rawdict.values())])
-
-
-# =====================================================================
-# --- network related functions
-# =====================================================================
-
-
-def net_io_counters(pernic=False):
- """Return network I/O statistics as a namedtuple including
- the following fields:
-
- - bytes_sent: number of bytes sent
- - bytes_recv: number of bytes received
- - packets_sent: number of packets sent
- - packets_recv: number of packets received
- - errin: total number of errors while receiving
- - errout: total number of errors while sending
- - dropin: total number of incoming packets which were dropped
- - dropout: total number of outgoing packets which were dropped
- (always 0 on OSX and BSD)
-
- If pernic is True return the same information for every
- network interface installed on the system as a dictionary
- with network interface names as the keys and the namedtuple
- described above as the values.
- """
- rawdict = _psplatform.net_io_counters()
- if not rawdict:
- raise RuntimeError("couldn't find any network interface")
- if pernic:
- for nic, fields in rawdict.items():
- rawdict[nic] = _common.snetio(*fields)
- return rawdict
- else:
- return _common.snetio(*[sum(x) for x in zip(*rawdict.values())])
-
-
-def net_connections(kind='inet'):
- """Return system-wide connections as a list of
- (fd, family, type, laddr, raddr, status, pid) namedtuples.
- In case of limited privileges 'fd' and 'pid' may be set to -1
- and None respectively.
- The 'kind' parameter filters for connections that fit the
- following criteria:
-
- Kind Value Connections using
- inet IPv4 and IPv6
- inet4 IPv4
- inet6 IPv6
- tcp TCP
- tcp4 TCP over IPv4
- tcp6 TCP over IPv6
- udp UDP
- udp4 UDP over IPv4
- udp6 UDP over IPv6
- unix UNIX socket (both UDP and TCP protocols)
- all the sum of all the possible families and protocols
-
- On OSX this function requires root privileges.
- """
- return _psplatform.net_connections(kind)
-
-
-def net_if_addrs():
- """Return the addresses associated to each NIC (network interface
- card) installed on the system as a dictionary whose keys are the
- NIC names and value is a list of namedtuples for each address
- assigned to the NIC. Each namedtuple includes 4 fields:
-
- - family
- - address
- - netmask
- - broadcast
-
- 'family' can be either socket.AF_INET, socket.AF_INET6 or
- psutil.AF_LINK, which refers to a MAC address.
- 'address' is the primary address, 'netmask' and 'broadcast'
- may be None.
- Note: you can have more than one address of the same family
- associated with each interface.
- """
- has_enums = sys.version_info >= (3, 4)
- if has_enums:
- import socket
- rawlist = _psplatform.net_if_addrs()
- rawlist.sort(key=lambda x: x[1]) # sort by family
- ret = collections.defaultdict(list)
- for name, fam, addr, mask, broadcast in rawlist:
- if has_enums:
- try:
- fam = socket.AddressFamily(fam)
- except ValueError:
- if os.name == 'nt' and fam == -1:
- fam = _psplatform.AF_LINK
- elif (hasattr(_psplatform, "AF_LINK") and
- _psplatform.AF_LINK == fam):
- # Linux defines AF_LINK as an alias for AF_PACKET.
- # We re-set the family here so that repr(family)
- # will show AF_LINK rather than AF_PACKET
- fam = _psplatform.AF_LINK
- ret[name].append(_common.snic(fam, addr, mask, broadcast))
- return dict(ret)
-
-
-def net_if_stats():
- """Return information about each NIC (network interface card)
- installed on the system as a dictionary whose keys are the
- NIC names and value is a namedtuple with the following fields:
-
- - isup: whether the interface is up (bool)
- - duplex: can be either NIC_DUPLEX_FULL, NIC_DUPLEX_HALF or
- NIC_DUPLEX_UNKNOWN
- - speed: the NIC speed expressed in mega bits (MB); if it can't
- be determined (e.g. 'localhost') it will be set to 0.
- - mtu: the maximum transmission unit expressed in bytes.
- """
- return _psplatform.net_if_stats()
-
-
-# =====================================================================
-# --- other system related functions
-# =====================================================================
-
-
-def boot_time():
- """Return the system boot time expressed in seconds since the epoch."""
- # Note: we are not caching this because it is subject to
- # system clock updates.
- return _psplatform.boot_time()
-
-
-def users():
- """Return users currently connected on the system as a list of
- namedtuples including the following fields.
-
- - user: the name of the user
- - terminal: the tty or pseudo-tty associated with the user, if any.
- - host: the host name associated with the entry, if any.
- - started: the creation time as a floating point number expressed in
- seconds since the epoch.
- """
- return _psplatform.users()
-
-
-def test():
- """List info of all currently running processes emulating ps aux
- output.
- """
- import datetime
-
- today_day = datetime.date.today()
- templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s %s"
- attrs = ['pid', 'cpu_percent', 'memory_percent', 'name', 'cpu_times',
- 'create_time', 'memory_info']
- if _POSIX:
- attrs.append('uids')
- attrs.append('terminal')
- print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
- "START", "TIME", "COMMAND"))
- for p in process_iter():
- try:
- pinfo = p.as_dict(attrs, ad_value='')
- except NoSuchProcess:
- pass
- else:
- if pinfo['create_time']:
- ctime = datetime.datetime.fromtimestamp(pinfo['create_time'])
- if ctime.date() == today_day:
- ctime = ctime.strftime("%H:%M")
- else:
- ctime = ctime.strftime("%b%d")
- else:
- ctime = ''
- cputime = time.strftime("%M:%S",
- time.localtime(sum(pinfo['cpu_times'])))
- try:
- user = p.username()
- except Error:
- user = ''
- if _WINDOWS and '\\' in user:
- user = user.split('\\')[1]
- vms = pinfo['memory_info'] and \
- int(pinfo['memory_info'].vms / 1024) or '?'
- rss = pinfo['memory_info'] and \
- int(pinfo['memory_info'].rss / 1024) or '?'
- memp = pinfo['memory_percent'] and \
- round(pinfo['memory_percent'], 1) or '?'
- print(templ % (
- user[:10],
- pinfo['pid'],
- pinfo['cpu_percent'],
- memp,
- vms,
- rss,
- pinfo.get('terminal', '') or '?',
- ctime,
- cputime,
- pinfo['name'].strip() or '?'))
-
-
-del memoize, division
-if sys.version_info < (3, 0):
- del num
-
-if __name__ == "__main__":
- test()
diff --git a/python/psutil/psutil/_common.py b/python/psutil/psutil/_common.py
deleted file mode 100644
index e9acf595d..000000000
--- a/python/psutil/psutil/_common.py
+++ /dev/null
@@ -1,246 +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.
-
-"""Common objects shared by all _ps* modules."""
-
-from __future__ import division
-import errno
-import functools
-import os
-import socket
-import stat
-import sys
-from collections import namedtuple
-from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
-
-if sys.version_info >= (3, 4):
- import enum
-else:
- enum = None
-
-
-# --- constants
-
-AF_INET6 = getattr(socket, 'AF_INET6', None)
-AF_UNIX = getattr(socket, 'AF_UNIX', None)
-
-STATUS_RUNNING = "running"
-STATUS_SLEEPING = "sleeping"
-STATUS_DISK_SLEEP = "disk-sleep"
-STATUS_STOPPED = "stopped"
-STATUS_TRACING_STOP = "tracing-stop"
-STATUS_ZOMBIE = "zombie"
-STATUS_DEAD = "dead"
-STATUS_WAKE_KILL = "wake-kill"
-STATUS_WAKING = "waking"
-STATUS_IDLE = "idle" # BSD
-STATUS_LOCKED = "locked" # BSD
-STATUS_WAITING = "waiting" # BSD
-
-CONN_ESTABLISHED = "ESTABLISHED"
-CONN_SYN_SENT = "SYN_SENT"
-CONN_SYN_RECV = "SYN_RECV"
-CONN_FIN_WAIT1 = "FIN_WAIT1"
-CONN_FIN_WAIT2 = "FIN_WAIT2"
-CONN_TIME_WAIT = "TIME_WAIT"
-CONN_CLOSE = "CLOSE"
-CONN_CLOSE_WAIT = "CLOSE_WAIT"
-CONN_LAST_ACK = "LAST_ACK"
-CONN_LISTEN = "LISTEN"
-CONN_CLOSING = "CLOSING"
-CONN_NONE = "NONE"
-
-if enum is None:
- NIC_DUPLEX_FULL = 2
- NIC_DUPLEX_HALF = 1
- NIC_DUPLEX_UNKNOWN = 0
-else:
- class NicDuplex(enum.IntEnum):
- NIC_DUPLEX_FULL = 2
- NIC_DUPLEX_HALF = 1
- NIC_DUPLEX_UNKNOWN = 0
-
- globals().update(NicDuplex.__members__)
-
-
-# --- functions
-
-def usage_percent(used, total, _round=None):
- """Calculate percentage usage of 'used' against 'total'."""
- try:
- ret = (used / total) * 100
- except ZeroDivisionError:
- ret = 0
- if _round is not None:
- return round(ret, _round)
- else:
- return ret
-
-
-def memoize(fun):
- """A simple memoize decorator for functions supporting (hashable)
- positional arguments.
- It also provides a cache_clear() function for clearing the cache:
-
- >>> @memoize
- ... def foo()
- ... return 1
- ...
- >>> foo()
- 1
- >>> foo.cache_clear()
- >>>
- """
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- key = (args, frozenset(sorted(kwargs.items())))
- lock.acquire()
- try:
- try:
- return cache[key]
- except KeyError:
- ret = cache[key] = fun(*args, **kwargs)
- finally:
- lock.release()
- return ret
-
- def cache_clear():
- """Clear cache."""
- lock.acquire()
- try:
- cache.clear()
- finally:
- lock.release()
-
- lock = threading.RLock()
- cache = {}
- wrapper.cache_clear = cache_clear
- return wrapper
-
-
-def isfile_strict(path):
- """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 sockfam_to_enum(num):
- """Convert a numeric socket family value to an IntEnum member.
- If it's not a known member, return the numeric value itself.
- """
- if enum is None:
- return num
- try:
- return socket.AddressFamily(num)
- except (ValueError, AttributeError):
- return num
-
-
-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
-
-conn_tmap = {
- "all": ([AF_INET, AF_INET6, AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
- "tcp": ([AF_INET, AF_INET6], [SOCK_STREAM]),
- "tcp4": ([AF_INET], [SOCK_STREAM]),
- "udp": ([AF_INET, AF_INET6], [SOCK_DGRAM]),
- "udp4": ([AF_INET], [SOCK_DGRAM]),
- "inet": ([AF_INET, AF_INET6], [SOCK_STREAM, SOCK_DGRAM]),
- "inet4": ([AF_INET], [SOCK_STREAM, SOCK_DGRAM]),
- "inet6": ([AF_INET6], [SOCK_STREAM, SOCK_DGRAM]),
-}
-
-if AF_INET6 is not None:
- conn_tmap.update({
- "tcp6": ([AF_INET6], [SOCK_STREAM]),
- "udp6": ([AF_INET6], [SOCK_DGRAM]),
- })
-
-if AF_UNIX is not None:
- conn_tmap.update({
- "unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
- })
-
-del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM
-
-
-# --- namedtuples for psutil.* system-related functions
-
-# psutil.swap_memory()
-sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
- 'sout'])
-# psutil.disk_usage()
-sdiskusage = namedtuple('sdiskusage', ['total', 'used', 'free', 'percent'])
-# psutil.disk_io_counters()
-sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
- 'read_bytes', 'write_bytes',
- 'read_time', 'write_time'])
-# psutil.disk_partitions()
-sdiskpart = namedtuple('sdiskpart', ['device', 'mountpoint', 'fstype', 'opts'])
-# psutil.net_io_counters()
-snetio = namedtuple('snetio', ['bytes_sent', 'bytes_recv',
- 'packets_sent', 'packets_recv',
- 'errin', 'errout',
- 'dropin', 'dropout'])
-# psutil.users()
-suser = namedtuple('suser', ['name', 'terminal', 'host', 'started'])
-# psutil.net_connections()
-sconn = namedtuple('sconn', ['fd', 'family', 'type', 'laddr', 'raddr',
- 'status', 'pid'])
-# psutil.net_if_addrs()
-snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast'])
-# psutil.net_if_stats()
-snicstats = namedtuple('snicstats', ['isup', 'duplex', 'speed', 'mtu'])
-
-
-# --- namedtuples for psutil.Process methods
-
-# psutil.Process.memory_info()
-pmem = namedtuple('pmem', ['rss', 'vms'])
-# psutil.Process.cpu_times()
-pcputimes = namedtuple('pcputimes', ['user', 'system'])
-# psutil.Process.open_files()
-popenfile = namedtuple('popenfile', ['path', 'fd'])
-# psutil.Process.threads()
-pthread = namedtuple('pthread', ['id', 'user_time', 'system_time'])
-# psutil.Process.uids()
-puids = namedtuple('puids', ['real', 'effective', 'saved'])
-# psutil.Process.gids()
-pgids = namedtuple('pgids', ['real', 'effective', 'saved'])
-# psutil.Process.io_counters()
-pio = namedtuple('pio', ['read_count', 'write_count',
- 'read_bytes', 'write_bytes'])
-# psutil.Process.ionice()
-pionice = namedtuple('pionice', ['ioclass', 'value'])
-# psutil.Process.ctx_switches()
-pctxsw = namedtuple('pctxsw', ['voluntary', 'involuntary'])
-# psutil.Process.connections()
-pconn = namedtuple('pconn', ['fd', 'family', 'type', 'laddr', 'raddr',
- 'status'])
diff --git a/python/psutil/psutil/_compat.py b/python/psutil/psutil/_compat.py
deleted file mode 100644
index 38744a84a..000000000
--- a/python/psutil/psutil/_compat.py
+++ /dev/null
@@ -1,189 +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.
-
-"""Module which provides compatibility with older Python versions."""
-
-import collections
-import functools
-import sys
-
-__all__ = ["PY3", "long", "xrange", "unicode", "callable", "lru_cache"]
-
-PY3 = sys.version_info[0] == 3
-
-if PY3:
- long = int
- xrange = range
- unicode = str
-
- def u(s):
- return s
-else:
- long = long
- xrange = xrange
- unicode = unicode
-
- def u(s):
- return unicode(s, "unicode_escape")
-
-
-# removed in 3.0, reintroduced in 3.2
-try:
- callable = callable
-except NameError:
- def callable(obj):
- return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
-
-
-# --- stdlib additions
-
-
-# py 3.2 functools.lru_cache
-# Taken from: http://code.activestate.com/recipes/578078
-# Credit: Raymond Hettinger
-try:
- from functools import lru_cache
-except ImportError:
- try:
- from threading import RLock
- except ImportError:
- from dummy_threading import RLock
-
- _CacheInfo = collections.namedtuple(
- "CacheInfo", ["hits", "misses", "maxsize", "currsize"])
-
- class _HashedSeq(list):
- __slots__ = 'hashvalue'
-
- def __init__(self, tup, hash=hash):
- self[:] = tup
- self.hashvalue = hash(tup)
-
- def __hash__(self):
- return self.hashvalue
-
- def _make_key(args, kwds, typed,
- kwd_mark=(object(), ),
- fasttypes=set((int, str, frozenset, type(None))),
- sorted=sorted, tuple=tuple, type=type, len=len):
- key = args
- if kwds:
- sorted_items = sorted(kwds.items())
- key += kwd_mark
- for item in sorted_items:
- key += item
- if typed:
- key += tuple(type(v) for v in args)
- if kwds:
- key += tuple(type(v) for k, v in sorted_items)
- elif len(key) == 1 and type(key[0]) in fasttypes:
- return key[0]
- return _HashedSeq(key)
-
- def lru_cache(maxsize=100, typed=False):
- """Least-recently-used cache decorator, see:
- http://docs.python.org/3/library/functools.html#functools.lru_cache
- """
- def decorating_function(user_function):
- cache = dict()
- stats = [0, 0]
- HITS, MISSES = 0, 1
- make_key = _make_key
- cache_get = cache.get
- _len = len
- lock = RLock()
- root = []
- root[:] = [root, root, None, None]
- nonlocal_root = [root]
- PREV, NEXT, KEY, RESULT = 0, 1, 2, 3
- if maxsize == 0:
- def wrapper(*args, **kwds):
- result = user_function(*args, **kwds)
- stats[MISSES] += 1
- return result
- elif maxsize is None:
- def wrapper(*args, **kwds):
- key = make_key(args, kwds, typed)
- result = cache_get(key, root)
- if result is not root:
- stats[HITS] += 1
- return result
- result = user_function(*args, **kwds)
- cache[key] = result
- stats[MISSES] += 1
- return result
- else:
- def wrapper(*args, **kwds):
- if kwds or typed:
- key = make_key(args, kwds, typed)
- else:
- key = args
- lock.acquire()
- try:
- link = cache_get(key)
- if link is not None:
- root, = nonlocal_root
- link_prev, link_next, key, result = link
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
- last = root[PREV]
- last[NEXT] = root[PREV] = link
- link[PREV] = last
- link[NEXT] = root
- stats[HITS] += 1
- return result
- finally:
- lock.release()
- result = user_function(*args, **kwds)
- lock.acquire()
- try:
- root, = nonlocal_root
- if key in cache:
- pass
- elif _len(cache) >= maxsize:
- oldroot = root
- oldroot[KEY] = key
- oldroot[RESULT] = result
- root = nonlocal_root[0] = oldroot[NEXT]
- oldkey = root[KEY]
- root[KEY] = root[RESULT] = None
- del cache[oldkey]
- cache[key] = oldroot
- else:
- last = root[PREV]
- link = [last, root, key, result]
- last[NEXT] = root[PREV] = cache[key] = link
- stats[MISSES] += 1
- finally:
- lock.release()
- return result
-
- def cache_info():
- """Report cache statistics"""
- lock.acquire()
- try:
- return _CacheInfo(stats[HITS], stats[MISSES], maxsize,
- len(cache))
- finally:
- lock.release()
-
- def cache_clear():
- """Clear the cache and cache statistics"""
- lock.acquire()
- try:
- cache.clear()
- root = nonlocal_root[0]
- root[:] = [root, root, None, None]
- stats[:] = [0, 0]
- finally:
- lock.release()
-
- wrapper.__wrapped__ = user_function
- wrapper.cache_info = cache_info
- wrapper.cache_clear = cache_clear
- return functools.update_wrapper(wrapper, user_function)
-
- return decorating_function
diff --git a/python/psutil/psutil/_psbsd.py b/python/psutil/psutil/_psbsd.py
deleted file mode 100644
index db54a02e1..000000000
--- a/python/psutil/psutil/_psbsd.py
+++ /dev/null
@@ -1,455 +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.
-
-"""FreeBSD platform implementation."""
-
-import errno
-import functools
-import os
-import xml.etree.ElementTree as ET
-from collections import namedtuple
-
-from . import _common
-from . import _psposix
-from . import _psutil_bsd as cext
-from . import _psutil_posix as cext_posix
-from ._common import conn_tmap, usage_percent, sockfam_to_enum
-from ._common import socktype_to_enum
-
-
-__extra__all__ = []
-
-# --- constants
-
-PROC_STATUSES = {
- cext.SSTOP: _common.STATUS_STOPPED,
- cext.SSLEEP: _common.STATUS_SLEEPING,
- cext.SRUN: _common.STATUS_RUNNING,
- cext.SIDL: _common.STATUS_IDLE,
- cext.SWAIT: _common.STATUS_WAITING,
- cext.SLOCK: _common.STATUS_LOCKED,
- cext.SZOMB: _common.STATUS_ZOMBIE,
-}
-
-TCP_STATUSES = {
- cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
- cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
- cext.TCPS_SYN_RECEIVED: _common.CONN_SYN_RECV,
- cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
- cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
- cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
- cext.TCPS_CLOSED: _common.CONN_CLOSE,
- cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
- cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
- cext.TCPS_LISTEN: _common.CONN_LISTEN,
- cext.TCPS_CLOSING: _common.CONN_CLOSING,
- cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
-}
-
-PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-AF_LINK = cext_posix.AF_LINK
-
-# extend base mem ntuple with BSD-specific memory metrics
-svmem = namedtuple(
- 'svmem', ['total', 'available', 'percent', 'used', 'free',
- 'active', 'inactive', 'buffers', 'cached', 'shared', 'wired'])
-scputimes = namedtuple(
- 'scputimes', ['user', 'nice', 'system', 'idle', 'irq'])
-pextmem = namedtuple('pextmem', ['rss', 'vms', 'text', 'data', 'stack'])
-pmmap_grouped = namedtuple(
- 'pmmap_grouped', 'path rss, private, ref_count, shadow_count')
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr, perms path rss, private, ref_count, shadow_count')
-
-# set later from __init__.py
-NoSuchProcess = None
-ZombieProcess = None
-AccessDenied = None
-TimeoutExpired = None
-
-
-def virtual_memory():
- """System virtual memory as a namedtuple."""
- mem = cext.virtual_mem()
- total, free, active, inactive, wired, cached, buffers, shared = mem
- avail = inactive + cached + free
- used = active + wired + cached
- percent = usage_percent((total - avail), total, _round=1)
- return svmem(total, avail, percent, used, free,
- active, inactive, buffers, cached, shared, wired)
-
-
-def swap_memory():
- """System swap memory as (total, used, free, sin, sout) namedtuple."""
- total, used, free, sin, sout = [x * PAGESIZE for x in cext.swap_mem()]
- percent = usage_percent(used, total, _round=1)
- return _common.sswap(total, used, free, percent, sin, sout)
-
-
-def cpu_times():
- """Return system per-CPU times as a namedtuple"""
- user, nice, system, idle, irq = cext.cpu_times()
- return scputimes(user, nice, system, idle, irq)
-
-
-if hasattr(cext, "per_cpu_times"):
- def per_cpu_times():
- """Return system CPU times as a namedtuple"""
- ret = []
- for cpu_t in cext.per_cpu_times():
- user, nice, system, idle, irq = cpu_t
- item = scputimes(user, nice, system, idle, irq)
- ret.append(item)
- return ret
-else:
- # XXX
- # Ok, this is very dirty.
- # On FreeBSD < 8 we cannot gather per-cpu information, see:
- # https://github.com/giampaolo/psutil/issues/226
- # If num cpus > 1, on first call we return single cpu times to avoid a
- # crash at psutil import time.
- # Next calls will fail with NotImplementedError
- def per_cpu_times():
- if cpu_count_logical() == 1:
- return [cpu_times()]
- if per_cpu_times.__called__:
- raise NotImplementedError("supported only starting from FreeBSD 8")
- per_cpu_times.__called__ = True
- return [cpu_times()]
-
- per_cpu_times.__called__ = False
-
-
-def cpu_count_logical():
- """Return the number of logical CPUs in the system."""
- return cext.cpu_count_logical()
-
-
-def cpu_count_physical():
- """Return the number of physical CPUs in the system."""
- # From the C module we'll get an XML string similar to this:
- # http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html
- # We may get None in case "sysctl kern.sched.topology_spec"
- # is not supported on this BSD version, in which case we'll mimic
- # os.cpu_count() and return None.
- ret = None
- s = cext.cpu_count_phys()
- if s is not None:
- # get rid of padding chars appended at the end of the string
- index = s.rfind("</groups>")
- if index != -1:
- s = s[:index + 9]
- root = ET.fromstring(s)
- try:
- ret = len(root.findall('group/children/group/cpu')) or None
- finally:
- # needed otherwise it will memleak
- root.clear()
- if not ret:
- # If logical CPUs are 1 it's obvious we'll have only 1
- # physical CPU.
- if cpu_count_logical() == 1:
- return 1
- return ret
-
-
-def boot_time():
- """The system boot time expressed in seconds since the epoch."""
- return cext.boot_time()
-
-
-def disk_partitions(all=False):
- retlist = []
- partitions = cext.disk_partitions()
- for partition in partitions:
- device, mountpoint, fstype, opts = partition
- if device == 'none':
- device = ''
- if not all:
- if not os.path.isabs(device) or not os.path.exists(device):
- continue
- ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
- retlist.append(ntuple)
- return retlist
-
-
-def users():
- retlist = []
- rawlist = cext.users()
- for item in rawlist:
- user, tty, hostname, tstamp = item
- if tty == '~':
- continue # reboot or shutdown
- nt = _common.suser(user, tty or None, hostname, tstamp)
- retlist.append(nt)
- return retlist
-
-
-def net_connections(kind):
- if kind not in _common.conn_tmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap])))
- families, types = conn_tmap[kind]
- ret = set()
- rawlist = cext.net_connections()
- for item in rawlist:
- fd, fam, type, laddr, raddr, status, pid = item
- # TODO: apply filter at C level
- if fam in families and type in types:
- try:
- status = TCP_STATUSES[status]
- except KeyError:
- # XXX: Not sure why this happens. I saw this occurring
- # with IPv6 sockets opened by 'vim'. Those sockets
- # have a very short lifetime so maybe the kernel
- # can't initialize their status?
- status = TCP_STATUSES[cext.PSUTIL_CONN_NONE]
- fam = sockfam_to_enum(fam)
- type = socktype_to_enum(type)
- nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid)
- ret.add(nt)
- return list(ret)
-
-
-def net_if_stats():
- """Get NIC stats (isup, duplex, speed, mtu)."""
- names = net_io_counters().keys()
- ret = {}
- for name in names:
- isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
- if hasattr(_common, 'NicDuplex'):
- duplex = _common.NicDuplex(duplex)
- ret[name] = _common.snicstats(isup, duplex, speed, mtu)
- return ret
-
-
-pids = cext.pids
-pid_exists = _psposix.pid_exists
-disk_usage = _psposix.disk_usage
-net_io_counters = cext.net_io_counters
-disk_io_counters = cext.disk_io_counters
-net_if_addrs = cext_posix.net_if_addrs
-
-
-def wrap_exceptions(fun):
- """Decorator which translates bare OSError exceptions into
- NoSuchProcess and AccessDenied.
- """
- @functools.wraps(fun)
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except OSError as err:
- # support for private module import
- if (NoSuchProcess is None or AccessDenied is None or
- ZombieProcess is None):
- raise
- if err.errno == errno.ESRCH:
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- if err.errno in (errno.EPERM, errno.EACCES):
- raise AccessDenied(self.pid, self._name)
- raise
- return wrapper
-
-
-class Process(object):
- """Wrapper class around underlying C implementation."""
-
- __slots__ = ["pid", "_name", "_ppid"]
-
- def __init__(self, pid):
- self.pid = pid
- self._name = None
- self._ppid = None
-
- @wrap_exceptions
- def name(self):
- return cext.proc_name(self.pid)
-
- @wrap_exceptions
- def exe(self):
- return cext.proc_exe(self.pid)
-
- @wrap_exceptions
- def cmdline(self):
- return cext.proc_cmdline(self.pid)
-
- @wrap_exceptions
- def terminal(self):
- tty_nr = cext.proc_tty_nr(self.pid)
- tmap = _psposix._get_terminal_map()
- try:
- return tmap[tty_nr]
- except KeyError:
- return None
-
- @wrap_exceptions
- def ppid(self):
- return cext.proc_ppid(self.pid)
-
- @wrap_exceptions
- def uids(self):
- real, effective, saved = cext.proc_uids(self.pid)
- return _common.puids(real, effective, saved)
-
- @wrap_exceptions
- def gids(self):
- real, effective, saved = cext.proc_gids(self.pid)
- return _common.pgids(real, effective, saved)
-
- @wrap_exceptions
- def cpu_times(self):
- user, system = cext.proc_cpu_times(self.pid)
- return _common.pcputimes(user, system)
-
- @wrap_exceptions
- def memory_info(self):
- rss, vms = cext.proc_memory_info(self.pid)[:2]
- return _common.pmem(rss, vms)
-
- @wrap_exceptions
- def memory_info_ex(self):
- return pextmem(*cext.proc_memory_info(self.pid))
-
- @wrap_exceptions
- def create_time(self):
- return cext.proc_create_time(self.pid)
-
- @wrap_exceptions
- def num_threads(self):
- return cext.proc_num_threads(self.pid)
-
- @wrap_exceptions
- def num_ctx_switches(self):
- return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
-
- @wrap_exceptions
- def threads(self):
- rawlist = cext.proc_threads(self.pid)
- retlist = []
- for thread_id, utime, stime in rawlist:
- ntuple = _common.pthread(thread_id, utime, stime)
- retlist.append(ntuple)
- return retlist
-
- @wrap_exceptions
- def connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap])))
- families, types = conn_tmap[kind]
- rawlist = cext.proc_connections(self.pid, families, types)
- ret = []
- for item in rawlist:
- fd, fam, type, laddr, raddr, status = item
- fam = sockfam_to_enum(fam)
- type = socktype_to_enum(type)
- status = TCP_STATUSES[status]
- nt = _common.pconn(fd, fam, type, laddr, raddr, status)
- ret.append(nt)
- return ret
-
- @wrap_exceptions
- def wait(self, timeout=None):
- try:
- return _psposix.wait_pid(self.pid, timeout)
- except _psposix.TimeoutExpired:
- # support for private module import
- if TimeoutExpired is None:
- raise
- raise TimeoutExpired(timeout, self.pid, self._name)
-
- @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 status(self):
- code = cext.proc_status(self.pid)
- if code in PROC_STATUSES:
- return PROC_STATUSES[code]
- # XXX is this legit? will we even ever get here?
- return "?"
-
- @wrap_exceptions
- def io_counters(self):
- rc, wc, rb, wb = cext.proc_io_counters(self.pid)
- return _common.pio(rc, wc, rb, wb)
-
- nt_mmap_grouped = namedtuple(
- 'mmap', 'path rss, private, ref_count, shadow_count')
- nt_mmap_ext = namedtuple(
- 'mmap', 'addr, perms path rss, private, ref_count, shadow_count')
-
- # FreeBSD < 8 does not support functions based on kinfo_getfile()
- # and kinfo_getvmmap()
- if hasattr(cext, 'proc_open_files'):
-
- @wrap_exceptions
- def open_files(self):
- """Return files opened by process as a list of namedtuples."""
- rawlist = cext.proc_open_files(self.pid)
- return [_common.popenfile(path, fd) for path, fd in rawlist]
-
- @wrap_exceptions
- def cwd(self):
- """Return process current working directory."""
- # sometimes we get an empty string, in which case we turn
- # it into None
- return cext.proc_cwd(self.pid) or None
-
- @wrap_exceptions
- def memory_maps(self):
- return cext.proc_memory_maps(self.pid)
-
- @wrap_exceptions
- def num_fds(self):
- """Return the number of file descriptors opened by this process."""
- return cext.proc_num_fds(self.pid)
-
- else:
- def _not_implemented(self):
- raise NotImplementedError("supported only starting from FreeBSD 8")
-
- 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
diff --git a/python/psutil/psutil/_pslinux.py b/python/psutil/psutil/_pslinux.py
deleted file mode 100644
index 7eb25f519..000000000
--- a/python/psutil/psutil/_pslinux.py
+++ /dev/null
@@ -1,1206 +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.
-
-"""Linux platform implementation."""
-
-from __future__ import division
-
-import base64
-import errno
-import functools
-import os
-import re
-import socket
-import struct
-import sys
-import warnings
-from collections import namedtuple, defaultdict
-
-from . import _common
-from . import _psposix
-from . import _psutil_linux as cext
-from . import _psutil_posix as cext_posix
-from ._common import isfile_strict, usage_percent
-from ._common import NIC_DUPLEX_FULL, NIC_DUPLEX_HALF, NIC_DUPLEX_UNKNOWN
-from ._compat import PY3, long
-
-if sys.version_info >= (3, 4):
- import enum
-else:
- enum = None
-
-
-__extra__all__ = [
- # io prio constants
- "IOPRIO_CLASS_NONE", "IOPRIO_CLASS_RT", "IOPRIO_CLASS_BE",
- "IOPRIO_CLASS_IDLE",
- # connection status constants
- "CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1",
- "CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
- "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", ]
-
-# --- constants
-
-HAS_PRLIMIT = hasattr(cext, "linux_prlimit")
-
-# RLIMIT_* constants, not guaranteed to be present on all kernels
-if HAS_PRLIMIT:
- for name in dir(cext):
- if name.startswith('RLIM'):
- __extra__all__.append(name)
-
-# Number of clock ticks per second
-CLOCK_TICKS = os.sysconf("SC_CLK_TCK")
-PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-BOOT_TIME = None # set later
-DEFAULT_ENCODING = sys.getdefaultencoding()
-if enum is None:
- AF_LINK = socket.AF_PACKET
-else:
- AddressFamily = enum.IntEnum('AddressFamily',
- {'AF_LINK': socket.AF_PACKET})
- AF_LINK = AddressFamily.AF_LINK
-
-# ioprio_* constants http://linux.die.net/man/2/ioprio_get
-if enum is None:
- IOPRIO_CLASS_NONE = 0
- IOPRIO_CLASS_RT = 1
- IOPRIO_CLASS_BE = 2
- IOPRIO_CLASS_IDLE = 3
-else:
- class IOPriority(enum.IntEnum):
- IOPRIO_CLASS_NONE = 0
- IOPRIO_CLASS_RT = 1
- IOPRIO_CLASS_BE = 2
- IOPRIO_CLASS_IDLE = 3
-
- globals().update(IOPriority.__members__)
-
-# taken from /fs/proc/array.c
-PROC_STATUSES = {
- "R": _common.STATUS_RUNNING,
- "S": _common.STATUS_SLEEPING,
- "D": _common.STATUS_DISK_SLEEP,
- "T": _common.STATUS_STOPPED,
- "t": _common.STATUS_TRACING_STOP,
- "Z": _common.STATUS_ZOMBIE,
- "X": _common.STATUS_DEAD,
- "x": _common.STATUS_DEAD,
- "K": _common.STATUS_WAKE_KILL,
- "W": _common.STATUS_WAKING
-}
-
-# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
-TCP_STATUSES = {
- "01": _common.CONN_ESTABLISHED,
- "02": _common.CONN_SYN_SENT,
- "03": _common.CONN_SYN_RECV,
- "04": _common.CONN_FIN_WAIT1,
- "05": _common.CONN_FIN_WAIT2,
- "06": _common.CONN_TIME_WAIT,
- "07": _common.CONN_CLOSE,
- "08": _common.CONN_CLOSE_WAIT,
- "09": _common.CONN_LAST_ACK,
- "0A": _common.CONN_LISTEN,
- "0B": _common.CONN_CLOSING
-}
-
-# set later from __init__.py
-NoSuchProcess = None
-ZombieProcess = None
-AccessDenied = None
-TimeoutExpired = None
-
-
-# --- named tuples
-
-def _get_cputimes_fields():
- """Return a namedtuple of variable fields depending on the
- CPU times available on this Linux kernel version which may be:
- (user, nice, system, idle, iowait, irq, softirq, [steal, [guest,
- [guest_nice]]])
- """
- with open('/proc/stat', 'rb') as f:
- values = f.readline().split()[1:]
- fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
- vlen = len(values)
- if vlen >= 8:
- # Linux >= 2.6.11
- fields.append('steal')
- if vlen >= 9:
- # Linux >= 2.6.24
- fields.append('guest')
- if vlen >= 10:
- # Linux >= 3.2.0
- fields.append('guest_nice')
- return fields
-
-
-scputimes = namedtuple('scputimes', _get_cputimes_fields())
-
-svmem = namedtuple(
- 'svmem', ['total', 'available', 'percent', 'used', 'free',
- 'active', 'inactive', 'buffers', 'cached'])
-
-pextmem = namedtuple('pextmem', 'rss vms shared text lib data dirty')
-
-pmmap_grouped = namedtuple(
- 'pmmap_grouped', ['path', 'rss', 'size', 'pss', 'shared_clean',
- 'shared_dirty', 'private_clean', 'private_dirty',
- 'referenced', 'anonymous', 'swap'])
-
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-
-
-# --- system memory
-
-def virtual_memory():
- total, free, buffers, shared, _, _ = cext.linux_sysinfo()
- cached = active = inactive = None
- with open('/proc/meminfo', 'rb') as f:
- for line in f:
- if line.startswith(b"Cached:"):
- cached = int(line.split()[1]) * 1024
- elif line.startswith(b"Active:"):
- active = int(line.split()[1]) * 1024
- elif line.startswith(b"Inactive:"):
- inactive = int(line.split()[1]) * 1024
- if (cached is not None and
- active is not None and
- inactive is not None):
- break
- else:
- # we might get here when dealing with exotic Linux flavors, see:
- # https://github.com/giampaolo/psutil/issues/313
- msg = "'cached', 'active' and 'inactive' memory stats couldn't " \
- "be determined and were set to 0"
- warnings.warn(msg, RuntimeWarning)
- cached = active = inactive = 0
- avail = free + buffers + cached
- used = total - free
- percent = usage_percent((total - avail), total, _round=1)
- return svmem(total, avail, percent, used, free,
- active, inactive, buffers, cached)
-
-
-def swap_memory():
- _, _, _, _, total, free = cext.linux_sysinfo()
- used = total - free
- percent = usage_percent(used, total, _round=1)
- # get pgin/pgouts
- with open("/proc/vmstat", "rb") as f:
- sin = sout = None
- for line in f:
- # values are expressed in 4 kilo bytes, we want bytes instead
- if line.startswith(b'pswpin'):
- sin = int(line.split(b' ')[1]) * 4 * 1024
- elif line.startswith(b'pswpout'):
- sout = int(line.split(b' ')[1]) * 4 * 1024
- if sin is not None and sout is not None:
- break
- else:
- # we might get here when dealing with exotic Linux flavors, see:
- # https://github.com/giampaolo/psutil/issues/313
- msg = "'sin' and 'sout' swap memory stats couldn't " \
- "be determined and were set to 0"
- warnings.warn(msg, RuntimeWarning)
- sin = sout = 0
- return _common.sswap(total, used, free, percent, sin, sout)
-
-
-# --- CPUs
-
-def cpu_times():
- """Return a named tuple representing the following system-wide
- CPU times:
- (user, nice, system, idle, iowait, irq, softirq [steal, [guest,
- [guest_nice]]])
- Last 3 fields may not be available on all Linux kernel versions.
- """
- with open('/proc/stat', 'rb') as f:
- values = f.readline().split()
- fields = values[1:len(scputimes._fields) + 1]
- fields = [float(x) / CLOCK_TICKS for x in fields]
- return scputimes(*fields)
-
-
-def per_cpu_times():
- """Return a list of namedtuple representing the CPU times
- for every CPU available on the system.
- """
- cpus = []
- with open('/proc/stat', 'rb') as f:
- # get rid of the first line which refers to system wide CPU stats
- f.readline()
- for line in f:
- if line.startswith(b'cpu'):
- values = line.split()
- fields = values[1:len(scputimes._fields) + 1]
- fields = [float(x) / CLOCK_TICKS for x in fields]
- entry = scputimes(*fields)
- cpus.append(entry)
- return cpus
-
-
-def cpu_count_logical():
- """Return the number of logical CPUs in the system."""
- try:
- return os.sysconf("SC_NPROCESSORS_ONLN")
- except ValueError:
- # as a second fallback we try to parse /proc/cpuinfo
- num = 0
- with open('/proc/cpuinfo', 'rb') as f:
- for line in f:
- if line.lower().startswith(b'processor'):
- num += 1
-
- # unknown format (e.g. amrel/sparc architectures), see:
- # https://github.com/giampaolo/psutil/issues/200
- # try to parse /proc/stat as a last resort
- if num == 0:
- search = re.compile('cpu\d')
- with open('/proc/stat', 'rt') as f:
- for line in f:
- line = line.split(' ')[0]
- if search.match(line):
- num += 1
-
- if num == 0:
- # mimic os.cpu_count()
- return None
- return num
-
-
-def cpu_count_physical():
- """Return the number of physical cores in the system."""
- mapping = {}
- current_info = {}
- with open('/proc/cpuinfo', 'rb') as f:
- for line in f:
- line = line.strip().lower()
- if not line:
- # new section
- if (b'physical id' in current_info and
- b'cpu cores' in current_info):
- mapping[current_info[b'physical id']] = \
- current_info[b'cpu cores']
- current_info = {}
- else:
- # ongoing section
- if (line.startswith(b'physical id') or
- line.startswith(b'cpu cores')):
- key, value = line.split(b'\t:', 1)
- current_info[key] = int(value)
-
- # mimic os.cpu_count()
- return sum(mapping.values()) or None
-
-
-# --- other system functions
-
-def users():
- """Return currently connected users as a list of namedtuples."""
- retlist = []
- rawlist = cext.users()
- for item in rawlist:
- user, tty, hostname, tstamp, user_process = item
- # note: the underlying C function includes entries about
- # system boot, run level and others. We might want
- # to use them in the future.
- if not user_process:
- continue
- if hostname == ':0.0' or hostname == ':0':
- hostname = 'localhost'
- nt = _common.suser(user, tty or None, hostname, tstamp)
- retlist.append(nt)
- return retlist
-
-
-def boot_time():
- """Return the system boot time expressed in seconds since the epoch."""
- global BOOT_TIME
- with open('/proc/stat', 'rb') as f:
- for line in f:
- if line.startswith(b'btime'):
- ret = float(line.strip().split()[1])
- BOOT_TIME = ret
- return ret
- raise RuntimeError("line 'btime' not found in /proc/stat")
-
-
-# --- processes
-
-def pids():
- """Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir(b'/proc') if x.isdigit()]
-
-
-def pid_exists(pid):
- """Check For the existence of a unix pid."""
- return _psposix.pid_exists(pid)
-
-
-# --- network
-
-class Connections:
- """A wrapper on top of /proc/net/* files, retrieving per-process
- and system-wide open connections (TCP, UDP, UNIX) similarly to
- "netstat -an".
-
- Note: in case of UNIX sockets we're only able to determine the
- local endpoint/path, not the one it's connected to.
- According to [1] it would be possible but not easily.
-
- [1] http://serverfault.com/a/417946
- """
-
- def __init__(self):
- tcp4 = ("tcp", socket.AF_INET, socket.SOCK_STREAM)
- tcp6 = ("tcp6", socket.AF_INET6, socket.SOCK_STREAM)
- udp4 = ("udp", socket.AF_INET, socket.SOCK_DGRAM)
- udp6 = ("udp6", socket.AF_INET6, socket.SOCK_DGRAM)
- unix = ("unix", socket.AF_UNIX, None)
- self.tmap = {
- "all": (tcp4, tcp6, udp4, udp6, unix),
- "tcp": (tcp4, tcp6),
- "tcp4": (tcp4,),
- "tcp6": (tcp6,),
- "udp": (udp4, udp6),
- "udp4": (udp4,),
- "udp6": (udp6,),
- "unix": (unix,),
- "inet": (tcp4, tcp6, udp4, udp6),
- "inet4": (tcp4, udp4),
- "inet6": (tcp6, udp6),
- }
-
- def get_proc_inodes(self, pid):
- inodes = defaultdict(list)
- for fd in os.listdir("/proc/%s/fd" % pid):
- try:
- inode = os.readlink("/proc/%s/fd/%s" % (pid, fd))
- except OSError as err:
- # ENOENT == file which is gone in the meantime;
- # os.stat('/proc/%s' % self.pid) will be done later
- # to force NSP (if it's the case)
- if err.errno in (errno.ENOENT, errno.ESRCH):
- continue
- elif err.errno == errno.EINVAL:
- # not a link
- continue
- else:
- raise
- else:
- if inode.startswith('socket:['):
- # the process is using a socket
- inode = inode[8:][:-1]
- inodes[inode].append((pid, int(fd)))
- return inodes
-
- def get_all_inodes(self):
- inodes = {}
- for pid in pids():
- try:
- inodes.update(self.get_proc_inodes(pid))
- except OSError as err:
- # os.listdir() is gonna raise a lot of access denied
- # exceptions in case of unprivileged user; that's fine
- # as we'll just end up returning a connection with PID
- # and fd set to None anyway.
- # Both netstat -an and lsof does the same so it's
- # unlikely we can do any better.
- # ENOENT just means a PID disappeared on us.
- if err.errno not in (
- errno.ENOENT, errno.ESRCH, errno.EPERM, errno.EACCES):
- raise
- return inodes
-
- def decode_address(self, addr, family):
- """Accept an "ip:port" address as displayed in /proc/net/*
- and convert it into a human readable form, like:
-
- "0500000A:0016" -> ("10.0.0.5", 22)
- "0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521)
-
- The IP address portion is a little or big endian four-byte
- hexadecimal number; that is, the least significant byte is listed
- first, so we need to reverse the order of the bytes to convert it
- to an IP address.
- The port is represented as a two-byte hexadecimal number.
-
- Reference:
- http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
- """
- ip, port = addr.split(':')
- port = int(port, 16)
- # this usually refers to a local socket in listen mode with
- # no end-points connected
- if not port:
- return ()
- if PY3:
- ip = ip.encode('ascii')
- if family == socket.AF_INET:
- # see: https://github.com/giampaolo/psutil/issues/201
- if sys.byteorder == 'little':
- ip = socket.inet_ntop(family, base64.b16decode(ip)[::-1])
- else:
- ip = socket.inet_ntop(family, base64.b16decode(ip))
- else: # IPv6
- # old version - let's keep it, just in case...
- # ip = ip.decode('hex')
- # return socket.inet_ntop(socket.AF_INET6,
- # ''.join(ip[i:i+4][::-1] for i in xrange(0, 16, 4)))
- ip = base64.b16decode(ip)
- # see: https://github.com/giampaolo/psutil/issues/201
- if sys.byteorder == 'little':
- ip = socket.inet_ntop(
- socket.AF_INET6,
- struct.pack('>4I', *struct.unpack('<4I', ip)))
- else:
- ip = socket.inet_ntop(
- socket.AF_INET6,
- struct.pack('<4I', *struct.unpack('<4I', ip)))
- return (ip, port)
-
- def process_inet(self, file, family, type_, inodes, filter_pid=None):
- """Parse /proc/net/tcp* and /proc/net/udp* files."""
- if file.endswith('6') and not os.path.exists(file):
- # IPv6 not supported
- return
- with open(file, 'rt') as f:
- f.readline() # skip the first line
- for line in f:
- try:
- _, laddr, raddr, status, _, _, _, _, _, inode = \
- line.split()[:10]
- except ValueError:
- raise RuntimeError(
- "error while parsing %s; malformed line %r" % (
- file, line))
- if inode in inodes:
- # # We assume inet sockets are unique, so we error
- # # out if there are multiple references to the
- # # same inode. We won't do this for UNIX sockets.
- # if len(inodes[inode]) > 1 and family != socket.AF_UNIX:
- # raise ValueError("ambiguos inode with multiple "
- # "PIDs references")
- pid, fd = inodes[inode][0]
- else:
- pid, fd = None, -1
- if filter_pid is not None and filter_pid != pid:
- continue
- else:
- if type_ == socket.SOCK_STREAM:
- status = TCP_STATUSES[status]
- else:
- status = _common.CONN_NONE
- laddr = self.decode_address(laddr, family)
- raddr = self.decode_address(raddr, family)
- yield (fd, family, type_, laddr, raddr, status, pid)
-
- def process_unix(self, file, family, inodes, filter_pid=None):
- """Parse /proc/net/unix files."""
- with open(file, 'rt') as f:
- f.readline() # skip the first line
- for line in f:
- tokens = line.split()
- try:
- _, _, _, _, type_, _, inode = tokens[0:7]
- except ValueError:
- raise RuntimeError(
- "error while parsing %s; malformed line %r" % (
- file, line))
- if inode in inodes:
- # With UNIX sockets we can have a single inode
- # referencing many file descriptors.
- pairs = inodes[inode]
- else:
- pairs = [(None, -1)]
- for pid, fd in pairs:
- if filter_pid is not None and filter_pid != pid:
- continue
- else:
- if len(tokens) == 8:
- path = tokens[-1]
- else:
- path = ""
- type_ = int(type_)
- raddr = None
- status = _common.CONN_NONE
- yield (fd, family, type_, path, raddr, status, pid)
-
- def retrieve(self, kind, pid=None):
- if kind not in self.tmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in self.tmap])))
- if pid is not None:
- inodes = self.get_proc_inodes(pid)
- if not inodes:
- # no connections for this process
- return []
- else:
- inodes = self.get_all_inodes()
- ret = set()
- for f, family, type_ in self.tmap[kind]:
- if family in (socket.AF_INET, socket.AF_INET6):
- ls = self.process_inet(
- "/proc/net/%s" % f, family, type_, inodes, filter_pid=pid)
- else:
- ls = self.process_unix(
- "/proc/net/%s" % f, family, inodes, filter_pid=pid)
- for fd, family, type_, laddr, raddr, status, bound_pid in ls:
- if pid:
- conn = _common.pconn(fd, family, type_, laddr, raddr,
- status)
- else:
- conn = _common.sconn(fd, family, type_, laddr, raddr,
- status, bound_pid)
- ret.add(conn)
- return list(ret)
-
-
-_connections = Connections()
-
-
-def net_connections(kind='inet'):
- """Return system-wide open connections."""
- return _connections.retrieve(kind)
-
-
-def net_io_counters():
- """Return network I/O statistics for every network interface
- installed on the system as a dict of raw tuples.
- """
- with open("/proc/net/dev", "rt") as f:
- lines = f.readlines()
- retdict = {}
- for line in lines[2:]:
- colon = line.rfind(':')
- assert colon > 0, repr(line)
- name = line[:colon].strip()
- fields = line[colon + 1:].strip().split()
- bytes_recv = int(fields[0])
- packets_recv = int(fields[1])
- errin = int(fields[2])
- dropin = int(fields[3])
- bytes_sent = int(fields[8])
- packets_sent = int(fields[9])
- errout = int(fields[10])
- dropout = int(fields[11])
- retdict[name] = (bytes_sent, bytes_recv, packets_sent, packets_recv,
- errin, errout, dropin, dropout)
- return retdict
-
-
-def net_if_stats():
- """Get NIC stats (isup, duplex, speed, mtu)."""
- duplex_map = {cext.DUPLEX_FULL: NIC_DUPLEX_FULL,
- cext.DUPLEX_HALF: NIC_DUPLEX_HALF,
- cext.DUPLEX_UNKNOWN: NIC_DUPLEX_UNKNOWN}
- names = net_io_counters().keys()
- ret = {}
- for name in names:
- isup, duplex, speed, mtu = cext.net_if_stats(name)
- duplex = duplex_map[duplex]
- ret[name] = _common.snicstats(isup, duplex, speed, mtu)
- return ret
-
-
-net_if_addrs = cext_posix.net_if_addrs
-
-
-# --- disks
-
-def disk_io_counters():
- """Return disk I/O statistics for every disk installed on the
- system as a dict of raw tuples.
- """
- # man iostat states that sectors are equivalent with blocks and
- # have a size of 512 bytes since 2.4 kernels. This value is
- # needed to calculate the amount of disk I/O in bytes.
- SECTOR_SIZE = 512
-
- # determine partitions we want to look for
- partitions = []
- with open("/proc/partitions", "rt") as f:
- lines = f.readlines()[2:]
- for line in reversed(lines):
- _, _, _, name = line.split()
- if name[-1].isdigit():
- # we're dealing with a partition (e.g. 'sda1'); 'sda' will
- # also be around but we want to omit it
- partitions.append(name)
- else:
- if not partitions or not partitions[-1].startswith(name):
- # we're dealing with a disk entity for which no
- # partitions have been defined (e.g. 'sda' but
- # 'sda1' was not around), see:
- # https://github.com/giampaolo/psutil/issues/338
- partitions.append(name)
- #
- retdict = {}
- with open("/proc/diskstats", "rt") as f:
- lines = f.readlines()
- for line in lines:
- # http://www.mjmwired.net/kernel/Documentation/iostats.txt
- fields = line.split()
- if len(fields) > 7:
- _, _, name, reads, _, rbytes, rtime, writes, _, wbytes, wtime = \
- fields[:11]
- else:
- # from kernel 2.6.0 to 2.6.25
- _, _, name, reads, rbytes, writes, wbytes = fields
- rtime, wtime = 0, 0
- if name in partitions:
- rbytes = int(rbytes) * SECTOR_SIZE
- wbytes = int(wbytes) * SECTOR_SIZE
- reads = int(reads)
- writes = int(writes)
- rtime = int(rtime)
- wtime = int(wtime)
- retdict[name] = (reads, writes, rbytes, wbytes, rtime, wtime)
- return retdict
-
-
-def disk_partitions(all=False):
- """Return mounted disk partitions as a list of namedtuples"""
- fstypes = set()
- with open("/proc/filesystems", "r") as f:
- for line in f:
- line = line.strip()
- if not line.startswith("nodev"):
- fstypes.add(line.strip())
- else:
- # ignore all lines starting with "nodev" except "nodev zfs"
- fstype = line.split("\t")[1]
- if fstype == "zfs":
- fstypes.add("zfs")
-
- retlist = []
- partitions = cext.disk_partitions()
- for partition in partitions:
- device, mountpoint, fstype, opts = partition
- if device == 'none':
- device = ''
- if not all:
- if device == '' or fstype not in fstypes:
- continue
- ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
- retlist.append(ntuple)
- return retlist
-
-
-disk_usage = _psposix.disk_usage
-
-
-# --- decorators
-
-def wrap_exceptions(fun):
- """Decorator which translates bare OSError and IOError exceptions
- into NoSuchProcess and AccessDenied.
- """
- @functools.wraps(fun)
- 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:
- 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):
- raise NoSuchProcess(self.pid, self._name)
- if err.errno in (errno.EPERM, errno.EACCES):
- raise AccessDenied(self.pid, self._name)
- raise
- return wrapper
-
-
-def wrap_exceptions_w_zombie(fun):
- """Same as above but also handles zombies."""
- @functools.wraps(fun)
- def wrapper(self, *args, **kwargs):
- try:
- return wrap_exceptions(fun)(self)
- except NoSuchProcess:
- if not pid_exists(self.pid):
- raise
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- return wrapper
-
-
-class Process(object):
- """Linux process implementation."""
-
- __slots__ = ["pid", "_name", "_ppid"]
-
- def __init__(self, pid):
- self.pid = pid
- self._name = None
- self._ppid = None
-
- @wrap_exceptions
- def name(self):
- fname = "/proc/%s/stat" % self.pid
- kw = dict(encoding=DEFAULT_ENCODING) if PY3 else dict()
- with open(fname, "rt", **kw) as f:
- data = f.read()
- # XXX - gets changed later and probably needs refactoring
- return data[data.find('(') + 1:data.rfind(')')]
-
- def exe(self):
- try:
- exe = os.readlink("/proc/%s/exe" % self.pid)
- except OSError as err:
- if err.errno in (errno.ENOENT, errno.ESRCH):
- # no such file error; might be raised also if the
- # path actually exists for system processes with
- # low pids (about 0-20)
- if os.path.lexists("/proc/%s" % self.pid):
- return ""
- else:
- 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
-
- # readlink() might return paths containing null bytes ('\x00').
- # Certain names have ' (deleted)' appended. Usually this is
- # bogus as the file actually exists. Either way that's not
- # important as we don't want to discriminate executables which
- # have been deleted.
- exe = exe.split('\x00')[0]
- if exe.endswith(' (deleted)') and not os.path.exists(exe):
- exe = exe[:-10]
- return exe
-
- @wrap_exceptions
- def cmdline(self):
- fname = "/proc/%s/cmdline" % self.pid
- kw = dict(encoding=DEFAULT_ENCODING) if PY3 else dict()
- with open(fname, "rt", **kw) as f:
- data = f.read()
- if data.endswith('\x00'):
- data = data[:-1]
- return [x for x in data.split('\x00')]
-
- @wrap_exceptions
- def terminal(self):
- tmap = _psposix._get_terminal_map()
- with open("/proc/%s/stat" % self.pid, 'rb') as f:
- tty_nr = int(f.read().split(b' ')[6])
- try:
- return tmap[tty_nr]
- except KeyError:
- return None
-
- if os.path.exists('/proc/%s/io' % os.getpid()):
- @wrap_exceptions
- def io_counters(self):
- fname = "/proc/%s/io" % self.pid
- with open(fname, 'rb') as f:
- rcount = wcount = rbytes = wbytes = None
- for line in f:
- if rcount is None and line.startswith(b"syscr"):
- rcount = int(line.split()[1])
- elif wcount is None and line.startswith(b"syscw"):
- wcount = int(line.split()[1])
- elif rbytes is None and line.startswith(b"read_bytes"):
- rbytes = int(line.split()[1])
- elif wbytes is None and line.startswith(b"write_bytes"):
- wbytes = int(line.split()[1])
- for x in (rcount, wcount, rbytes, wbytes):
- if x is None:
- raise NotImplementedError(
- "couldn't read all necessary info from %r" % fname)
- return _common.pio(rcount, wcount, rbytes, wbytes)
- else:
- def io_counters(self):
- raise NotImplementedError("couldn't find /proc/%s/io (kernel "
- "too old?)" % self.pid)
-
- @wrap_exceptions
- def cpu_times(self):
- with open("/proc/%s/stat" % self.pid, 'rb') as f:
- st = f.read().strip()
- # ignore the first two values ("pid (exe)")
- st = st[st.find(b')') + 2:]
- values = st.split(b' ')
- utime = float(values[11]) / CLOCK_TICKS
- stime = float(values[12]) / CLOCK_TICKS
- return _common.pcputimes(utime, stime)
-
- @wrap_exceptions
- def wait(self, timeout=None):
- try:
- return _psposix.wait_pid(self.pid, timeout)
- except _psposix.TimeoutExpired:
- # support for private module import
- if TimeoutExpired is None:
- raise
- raise TimeoutExpired(timeout, self.pid, self._name)
-
- @wrap_exceptions
- def create_time(self):
- with open("/proc/%s/stat" % self.pid, 'rb') as f:
- st = f.read().strip()
- # ignore the first two values ("pid (exe)")
- st = st[st.rfind(b')') + 2:]
- values = st.split(b' ')
- # According to documentation, starttime is in field 21 and the
- # unit is jiffies (clock ticks).
- # We first divide it for clock ticks and then add uptime returning
- # seconds since the epoch, in UTC.
- # Also use cached value if available.
- bt = BOOT_TIME or boot_time()
- return (float(values[19]) / CLOCK_TICKS) + bt
-
- @wrap_exceptions
- def memory_info(self):
- with open("/proc/%s/statm" % self.pid, 'rb') as f:
- vms, rss = f.readline().split()[:2]
- return _common.pmem(int(rss) * PAGESIZE,
- int(vms) * PAGESIZE)
-
- @wrap_exceptions
- def memory_info_ex(self):
- # ============================================================
- # | FIELD | DESCRIPTION | AKA | TOP |
- # ============================================================
- # | rss | resident set size | | RES |
- # | vms | total program size | size | VIRT |
- # | shared | shared pages (from shared mappings) | | SHR |
- # | text | text ('code') | trs | CODE |
- # | lib | library (unused in Linux 2.6) | lrs | |
- # | data | data + stack | drs | DATA |
- # | dirty | dirty pages (unused in Linux 2.6) | dt | |
- # ============================================================
- with open("/proc/%s/statm" % self.pid, "rb") as f:
- vms, rss, shared, text, lib, data, dirty = \
- [int(x) * PAGESIZE for x in f.readline().split()[:7]]
- return pextmem(rss, vms, shared, text, lib, data, dirty)
-
- if os.path.exists('/proc/%s/smaps' % os.getpid()):
-
- @wrap_exceptions
- def memory_maps(self):
- """Return process's mapped memory regions as a list of named tuples.
- Fields are explained in 'man proc'; here is an updated (Apr 2012)
- version: http://goo.gl/fmebo
- """
- with open("/proc/%s/smaps" % self.pid, "rt") as f:
- first_line = f.readline()
- current_block = [first_line]
-
- def get_blocks():
- data = {}
- for line in f:
- fields = line.split(None, 5)
- if not fields[0].endswith(':'):
- # new block section
- yield (current_block.pop(), data)
- current_block.append(line)
- else:
- try:
- data[fields[0]] = int(fields[1]) * 1024
- except ValueError:
- if fields[0].startswith('VmFlags:'):
- # see issue #369
- continue
- else:
- raise ValueError("don't know how to inte"
- "rpret line %r" % line)
- yield (current_block.pop(), data)
-
- ls = []
- if first_line: # smaps file can be empty
- for header, data in get_blocks():
- hfields = header.split(None, 5)
- try:
- addr, perms, offset, dev, inode, path = hfields
- except ValueError:
- addr, perms, offset, dev, inode, path = \
- hfields + ['']
- if not path:
- path = '[anon]'
- else:
- path = path.strip()
- ls.append((
- addr, perms, path,
- data['Rss:'],
- data.get('Size:', 0),
- data.get('Pss:', 0),
- data.get('Shared_Clean:', 0),
- data.get('Shared_Dirty:', 0),
- data.get('Private_Clean:', 0),
- data.get('Private_Dirty:', 0),
- data.get('Referenced:', 0),
- data.get('Anonymous:', 0),
- data.get('Swap:', 0)
- ))
- return ls
-
- else:
- def memory_maps(self):
- msg = "couldn't find /proc/%s/smaps; kernel < 2.6.14 or " \
- "CONFIG_MMU kernel configuration option is not enabled" \
- % self.pid
- raise NotImplementedError(msg)
-
- @wrap_exceptions_w_zombie
- def cwd(self):
- # readlink() might return paths containing null bytes causing
- # problems when used with other fs-related functions (os.*,
- # open(), ...)
- path = os.readlink("/proc/%s/cwd" % self.pid)
- return path.replace('\x00', '')
-
- @wrap_exceptions
- def num_ctx_switches(self):
- vol = unvol = None
- with open("/proc/%s/status" % self.pid, "rb") as f:
- for line in f:
- if line.startswith(b"voluntary_ctxt_switches"):
- vol = int(line.split()[1])
- elif line.startswith(b"nonvoluntary_ctxt_switches"):
- unvol = int(line.split()[1])
- if vol is not None and unvol is not None:
- return _common.pctxsw(vol, unvol)
- raise NotImplementedError(
- "'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'"
- "fields were not found in /proc/%s/status; the kernel is "
- "probably older than 2.6.23" % self.pid)
-
- @wrap_exceptions
- def num_threads(self):
- with open("/proc/%s/status" % self.pid, "rb") as f:
- for line in f:
- if line.startswith(b"Threads:"):
- return int(line.split()[1])
- raise NotImplementedError("line not found")
-
- @wrap_exceptions
- def threads(self):
- thread_ids = os.listdir("/proc/%s/task" % self.pid)
- thread_ids.sort()
- retlist = []
- hit_enoent = False
- for thread_id in thread_ids:
- fname = "/proc/%s/task/%s/stat" % (self.pid, thread_id)
- try:
- with open(fname, 'rb') as f:
- st = f.read().strip()
- except IOError as err:
- if err.errno == errno.ENOENT:
- # no such file or directory; it means thread
- # disappeared on us
- hit_enoent = True
- continue
- raise
- # ignore the first two values ("pid (exe)")
- st = st[st.find(b')') + 2:]
- values = st.split(b' ')
- utime = float(values[11]) / CLOCK_TICKS
- stime = float(values[12]) / CLOCK_TICKS
- ntuple = _common.pthread(int(thread_id), utime, stime)
- retlist.append(ntuple)
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return retlist
-
- @wrap_exceptions
- def nice_get(self):
- # with open('/proc/%s/stat' % self.pid, 'r') as f:
- # data = f.read()
- # return int(data.split()[18])
-
- # Use C implementation
- return cext_posix.getpriority(self.pid)
-
- @wrap_exceptions
- def nice_set(self, value):
- return cext_posix.setpriority(self.pid, value)
-
- @wrap_exceptions
- def cpu_affinity_get(self):
- return cext.proc_cpu_affinity_get(self.pid)
-
- @wrap_exceptions
- def cpu_affinity_set(self, cpus):
- try:
- cext.proc_cpu_affinity_set(self.pid, cpus)
- except OSError as err:
- if err.errno == errno.EINVAL:
- 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))
- raise
-
- # only starting from kernel 2.6.13
- if hasattr(cext, "proc_ioprio_get"):
-
- @wrap_exceptions
- def ionice_get(self):
- ioclass, value = cext.proc_ioprio_get(self.pid)
- if enum is not None:
- ioclass = IOPriority(ioclass)
- return _common.pionice(ioclass, value)
-
- @wrap_exceptions
- def ionice_set(self, ioclass, value):
- if value is not None:
- if not PY3 and not isinstance(value, (int, long)):
- msg = "value argument is not an integer (gor %r)" % value
- raise TypeError(msg)
- if not 0 <= value <= 8:
- raise ValueError(
- "value argument range expected is between 0 and 8")
-
- if ioclass in (IOPRIO_CLASS_NONE, None):
- if value:
- msg = "can't specify value with IOPRIO_CLASS_NONE " \
- "(got %r)" % value
- raise ValueError(msg)
- ioclass = IOPRIO_CLASS_NONE
- value = 0
- elif ioclass == IOPRIO_CLASS_IDLE:
- if value:
- msg = "can't specify value with IOPRIO_CLASS_IDLE " \
- "(got %r)" % value
- raise ValueError(msg)
- value = 0
- elif ioclass in (IOPRIO_CLASS_RT, IOPRIO_CLASS_BE):
- if value is None:
- # TODO: add comment explaining why this is 4 (?)
- value = 4
- else:
- # otherwise we would get OSError(EVINAL)
- raise ValueError("invalid ioclass argument %r" % ioclass)
-
- return cext.proc_ioprio_set(self.pid, ioclass, value)
-
- if HAS_PRLIMIT:
- @wrap_exceptions
- def rlimit(self, resource, limits=None):
- # If pid is 0 prlimit() applies to the calling process and
- # we don't want that. We should never get here though as
- # PID 0 is not supported on Linux.
- if self.pid == 0:
- raise ValueError("can't use prlimit() against PID 0 process")
- try:
- if limits is None:
- # get
- return cext.linux_prlimit(self.pid, resource)
- else:
- # set
- if len(limits) != 2:
- raise ValueError(
- "second argument must be a (soft, hard) tuple, "
- "got %s" % repr(limits))
- soft, hard = limits
- cext.linux_prlimit(self.pid, resource, soft, hard)
- except OSError as err:
- if err.errno == errno.ENOSYS and pid_exists(self.pid):
- # I saw this happening on Travis:
- # https://travis-ci.org/giampaolo/psutil/jobs/51368273
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- raise
-
- @wrap_exceptions
- def status(self):
- with open("/proc/%s/status" % self.pid, 'rb') as f:
- for line in f:
- if line.startswith(b"State:"):
- letter = line.split()[1]
- if PY3:
- letter = letter.decode()
- # XXX is '?' legit? (we're not supposed to return
- # it anyway)
- return PROC_STATUSES.get(letter, '?')
-
- @wrap_exceptions
- def open_files(self):
- retlist = []
- files = os.listdir("/proc/%s/fd" % self.pid)
- hit_enoent = False
- for fd in files:
- file = "/proc/%s/fd/%s" % (self.pid, fd)
- try:
- file = os.readlink(file)
- except OSError as err:
- # ENOENT == file which is gone in the meantime
- if err.errno in (errno.ENOENT, errno.ESRCH):
- hit_enoent = True
- continue
- elif err.errno == errno.EINVAL:
- # not a link
- continue
- else:
- raise
- else:
- # If file is not an absolute path there's no way
- # to tell whether it's a regular file or not,
- # so we skip it. A regular file is always supposed
- # to be absolutized though.
- if file.startswith('/') and isfile_strict(file):
- ntuple = _common.popenfile(file, int(fd))
- retlist.append(ntuple)
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return retlist
-
- @wrap_exceptions
- def connections(self, kind='inet'):
- ret = _connections.retrieve(kind, self.pid)
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return ret
-
- @wrap_exceptions
- def num_fds(self):
- return len(os.listdir("/proc/%s/fd" % self.pid))
-
- @wrap_exceptions
- def ppid(self):
- fpath = "/proc/%s/status" % self.pid
- with open(fpath, 'rb') as f:
- for line in f:
- if line.startswith(b"PPid:"):
- # PPid: nnnn
- return int(line.split()[1])
- raise NotImplementedError("line 'PPid' not found in %s" % fpath)
-
- @wrap_exceptions
- def uids(self):
- fpath = "/proc/%s/status" % self.pid
- with open(fpath, 'rb') as f:
- for line in f:
- if line.startswith(b'Uid:'):
- _, real, effective, saved, fs = line.split()
- return _common.puids(int(real), int(effective), int(saved))
- raise NotImplementedError("line 'Uid' not found in %s" % fpath)
-
- @wrap_exceptions
- def gids(self):
- fpath = "/proc/%s/status" % self.pid
- with open(fpath, 'rb') as f:
- for line in f:
- if line.startswith(b'Gid:'):
- _, real, effective, saved, fs = line.split()
- return _common.pgids(int(real), int(effective), int(saved))
- raise NotImplementedError("line 'Gid' not found in %s" % fpath)
diff --git a/python/psutil/psutil/_psosx.py b/python/psutil/psutil/_psosx.py
deleted file mode 100644
index 41875fe40..000000000
--- a/python/psutil/psutil/_psosx.py
+++ /dev/null
@@ -1,363 +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.
-
-"""OSX platform implementation."""
-
-import errno
-import functools
-import os
-from collections import namedtuple
-
-from . import _common
-from . import _psposix
-from . import _psutil_osx as cext
-from . import _psutil_posix as cext_posix
-from ._common import conn_tmap, usage_percent, isfile_strict
-from ._common import sockfam_to_enum, socktype_to_enum
-
-
-__extra__all__ = []
-
-# --- constants
-
-PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-AF_LINK = cext_posix.AF_LINK
-
-# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
-TCP_STATUSES = {
- cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
- cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
- cext.TCPS_SYN_RECEIVED: _common.CONN_SYN_RECV,
- cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
- cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
- cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
- cext.TCPS_CLOSED: _common.CONN_CLOSE,
- cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
- cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
- cext.TCPS_LISTEN: _common.CONN_LISTEN,
- cext.TCPS_CLOSING: _common.CONN_CLOSING,
- cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
-}
-
-PROC_STATUSES = {
- cext.SIDL: _common.STATUS_IDLE,
- cext.SRUN: _common.STATUS_RUNNING,
- cext.SSLEEP: _common.STATUS_SLEEPING,
- cext.SSTOP: _common.STATUS_STOPPED,
- cext.SZOMB: _common.STATUS_ZOMBIE,
-}
-
-scputimes = namedtuple('scputimes', ['user', 'nice', 'system', 'idle'])
-
-svmem = namedtuple(
- 'svmem', ['total', 'available', 'percent', 'used', 'free',
- 'active', 'inactive', 'wired'])
-
-pextmem = namedtuple('pextmem', ['rss', 'vms', 'pfaults', 'pageins'])
-
-pmmap_grouped = namedtuple(
- 'pmmap_grouped',
- 'path rss private swapped dirtied ref_count shadow_depth')
-
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-
-# set later from __init__.py
-NoSuchProcess = None
-ZombieProcess = None
-AccessDenied = None
-TimeoutExpired = None
-
-
-# --- functions
-
-def virtual_memory():
- """System virtual memory as a namedtuple."""
- total, active, inactive, wired, free = cext.virtual_mem()
- avail = inactive + free
- used = active + inactive + wired
- percent = usage_percent((total - avail), total, _round=1)
- return svmem(total, avail, percent, used, free,
- active, inactive, wired)
-
-
-def swap_memory():
- """Swap system memory as a (total, used, free, sin, sout) tuple."""
- total, used, free, sin, sout = cext.swap_mem()
- percent = usage_percent(used, total, _round=1)
- return _common.sswap(total, used, free, percent, sin, sout)
-
-
-def cpu_times():
- """Return system CPU times as a namedtuple."""
- user, nice, system, idle = cext.cpu_times()
- return scputimes(user, nice, system, idle)
-
-
-def per_cpu_times():
- """Return system CPU times as a named tuple"""
- ret = []
- for cpu_t in cext.per_cpu_times():
- user, nice, system, idle = cpu_t
- item = scputimes(user, nice, system, idle)
- ret.append(item)
- return ret
-
-
-def cpu_count_logical():
- """Return the number of logical CPUs in the system."""
- return cext.cpu_count_logical()
-
-
-def cpu_count_physical():
- """Return the number of physical CPUs in the system."""
- return cext.cpu_count_phys()
-
-
-def boot_time():
- """The system boot time expressed in seconds since the epoch."""
- return cext.boot_time()
-
-
-def disk_partitions(all=False):
- retlist = []
- partitions = cext.disk_partitions()
- for partition in partitions:
- device, mountpoint, fstype, opts = partition
- if device == 'none':
- device = ''
- if not all:
- if not os.path.isabs(device) or not os.path.exists(device):
- continue
- ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
- retlist.append(ntuple)
- return retlist
-
-
-def users():
- retlist = []
- rawlist = cext.users()
- for item in rawlist:
- user, tty, hostname, tstamp = item
- if tty == '~':
- continue # reboot or shutdown
- if not tstamp:
- continue
- nt = _common.suser(user, tty or None, hostname or None, tstamp)
- retlist.append(nt)
- return retlist
-
-
-def net_connections(kind='inet'):
- # Note: on OSX this will fail with AccessDenied unless
- # the process is owned by root.
- ret = []
- for pid in pids():
- try:
- cons = Process(pid).connections(kind)
- except NoSuchProcess:
- continue
- else:
- if cons:
- for c in cons:
- c = list(c) + [pid]
- ret.append(_common.sconn(*c))
- return ret
-
-
-def net_if_stats():
- """Get NIC stats (isup, duplex, speed, mtu)."""
- names = net_io_counters().keys()
- ret = {}
- for name in names:
- isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
- if hasattr(_common, 'NicDuplex'):
- duplex = _common.NicDuplex(duplex)
- ret[name] = _common.snicstats(isup, duplex, speed, mtu)
- return ret
-
-
-pids = cext.pids
-pid_exists = _psposix.pid_exists
-disk_usage = _psposix.disk_usage
-net_io_counters = cext.net_io_counters
-disk_io_counters = cext.disk_io_counters
-net_if_addrs = cext_posix.net_if_addrs
-
-
-def wrap_exceptions(fun):
- """Decorator which translates bare OSError exceptions into
- NoSuchProcess and AccessDenied.
- """
- @functools.wraps(fun)
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except OSError as err:
- # support for private module import
- if (NoSuchProcess is None or AccessDenied is None or
- ZombieProcess is None):
- raise
- if err.errno == errno.ESRCH:
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- if err.errno in (errno.EPERM, errno.EACCES):
- raise AccessDenied(self.pid, self._name)
- raise
- return wrapper
-
-
-class Process(object):
- """Wrapper class around underlying C implementation."""
-
- __slots__ = ["pid", "_name", "_ppid"]
-
- def __init__(self, pid):
- self.pid = pid
- self._name = None
- self._ppid = None
-
- @wrap_exceptions
- def name(self):
- return cext.proc_name(self.pid)
-
- @wrap_exceptions
- def exe(self):
- return cext.proc_exe(self.pid)
-
- @wrap_exceptions
- def cmdline(self):
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- return cext.proc_cmdline(self.pid)
-
- @wrap_exceptions
- def ppid(self):
- return cext.proc_ppid(self.pid)
-
- @wrap_exceptions
- def cwd(self):
- return cext.proc_cwd(self.pid)
-
- @wrap_exceptions
- def uids(self):
- real, effective, saved = cext.proc_uids(self.pid)
- return _common.puids(real, effective, saved)
-
- @wrap_exceptions
- def gids(self):
- real, effective, saved = cext.proc_gids(self.pid)
- return _common.pgids(real, effective, saved)
-
- @wrap_exceptions
- def terminal(self):
- tty_nr = cext.proc_tty_nr(self.pid)
- tmap = _psposix._get_terminal_map()
- try:
- return tmap[tty_nr]
- except KeyError:
- return None
-
- @wrap_exceptions
- def memory_info(self):
- rss, vms = cext.proc_memory_info(self.pid)[:2]
- return _common.pmem(rss, vms)
-
- @wrap_exceptions
- def memory_info_ex(self):
- rss, vms, pfaults, pageins = cext.proc_memory_info(self.pid)
- return pextmem(rss, vms, pfaults * PAGESIZE, pageins * PAGESIZE)
-
- @wrap_exceptions
- def cpu_times(self):
- user, system = cext.proc_cpu_times(self.pid)
- return _common.pcputimes(user, system)
-
- @wrap_exceptions
- def create_time(self):
- return cext.proc_create_time(self.pid)
-
- @wrap_exceptions
- def num_ctx_switches(self):
- return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
-
- @wrap_exceptions
- def num_threads(self):
- return cext.proc_num_threads(self.pid)
-
- @wrap_exceptions
- def open_files(self):
- if self.pid == 0:
- return []
- files = []
- rawlist = cext.proc_open_files(self.pid)
- for path, fd in rawlist:
- if isfile_strict(path):
- ntuple = _common.popenfile(path, fd)
- files.append(ntuple)
- return files
-
- @wrap_exceptions
- def connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap])))
- families, types = conn_tmap[kind]
- rawlist = cext.proc_connections(self.pid, families, types)
- ret = []
- for item in rawlist:
- fd, fam, type, laddr, raddr, status = item
- status = TCP_STATUSES[status]
- fam = sockfam_to_enum(fam)
- type = socktype_to_enum(type)
- nt = _common.pconn(fd, fam, type, laddr, raddr, status)
- ret.append(nt)
- return ret
-
- @wrap_exceptions
- def num_fds(self):
- if self.pid == 0:
- return 0
- return cext.proc_num_fds(self.pid)
-
- @wrap_exceptions
- def wait(self, timeout=None):
- try:
- return _psposix.wait_pid(self.pid, timeout)
- except _psposix.TimeoutExpired:
- # support for private module import
- if TimeoutExpired is None:
- raise
- raise TimeoutExpired(timeout, self.pid, self._name)
-
- @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 status(self):
- code = cext.proc_status(self.pid)
- # XXX is '?' legit? (we're not supposed to return it anyway)
- return PROC_STATUSES.get(code, '?')
-
- @wrap_exceptions
- def threads(self):
- rawlist = cext.proc_threads(self.pid)
- retlist = []
- for thread_id, utime, stime in rawlist:
- ntuple = _common.pthread(thread_id, utime, stime)
- retlist.append(ntuple)
- return retlist
-
- @wrap_exceptions
- def memory_maps(self):
- return cext.proc_memory_maps(self.pid)
diff --git a/python/psutil/psutil/_psposix.py b/python/psutil/psutil/_psposix.py
deleted file mode 100644
index 5bb16a386..000000000
--- a/python/psutil/psutil/_psposix.py
+++ /dev/null
@@ -1,156 +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.
-
-"""Routines common to all posix systems."""
-
-import errno
-import glob
-import os
-import sys
-import time
-
-from ._common import sdiskusage, usage_percent, memoize
-from ._compat import PY3, unicode
-
-
-class TimeoutExpired(Exception):
- pass
-
-
-def pid_exists(pid):
- """Check whether pid exists in the current process table."""
- if pid == 0:
- # According to "man 2 kill" PID 0 has a special meaning:
- # it refers to <<every process in the process group of the
- # calling process>> so we don't want to go any further.
- # If we get here it means this UNIX platform *does* have
- # a process with id 0.
- return True
- try:
- os.kill(pid, 0)
- except OSError as err:
- if err.errno == errno.ESRCH:
- # ESRCH == No such process
- return False
- elif err.errno == errno.EPERM:
- # EPERM clearly means there's a process to deny access to
- return True
- else:
- # According to "man 2 kill" possible error values are
- # (EINVAL, EPERM, ESRCH) therefore we should never get
- # here. If we do let's be explicit in considering this
- # an error.
- raise err
- else:
- return True
-
-
-def wait_pid(pid, timeout=None):
- """Wait for process with pid 'pid' to terminate and return its
- exit status code as an integer.
-
- If pid is not a children of os.getpid() (current process) just
- waits until the process disappears and return None.
-
- If pid does not exist at all return None immediately.
-
- Raise TimeoutExpired on timeout expired.
- """
- def check_timeout(delay):
- if timeout is not None:
- if timer() >= stop_at:
- raise TimeoutExpired()
- time.sleep(delay)
- return min(delay * 2, 0.04)
-
- timer = getattr(time, 'monotonic', time.time)
- if timeout is not None:
- def waitcall():
- return os.waitpid(pid, os.WNOHANG)
- stop_at = timer() + timeout
- else:
- def waitcall():
- return os.waitpid(pid, 0)
-
- delay = 0.0001
- while True:
- try:
- retpid, status = waitcall()
- except OSError as err:
- if err.errno == errno.EINTR:
- delay = check_timeout(delay)
- continue
- elif err.errno == errno.ECHILD:
- # This has two meanings:
- # - pid is not a child of os.getpid() in which case
- # we keep polling until it's gone
- # - pid never existed in the first place
- # In both cases we'll eventually return None as we
- # can't determine its exit status code.
- while True:
- if pid_exists(pid):
- delay = check_timeout(delay)
- else:
- return
- else:
- raise
- else:
- if retpid == 0:
- # WNOHANG was used, pid is still running
- delay = check_timeout(delay)
- continue
- # process exited due to a signal; return the integer of
- # that signal
- if os.WIFSIGNALED(status):
- return os.WTERMSIG(status)
- # process exited using exit(2) system call; return the
- # integer exit(2) system call has been called with
- elif os.WIFEXITED(status):
- return os.WEXITSTATUS(status)
- else:
- # should never happen
- raise RuntimeError("unknown process exit status")
-
-
-def disk_usage(path):
- """Return disk usage associated with path."""
- try:
- st = os.statvfs(path)
- except UnicodeEncodeError:
- if not PY3 and isinstance(path, unicode):
- # this is a bug with os.statvfs() and unicode on
- # Python 2, see:
- # - https://github.com/giampaolo/psutil/issues/416
- # - http://bugs.python.org/issue18695
- try:
- path = path.encode(sys.getfilesystemencoding())
- except UnicodeEncodeError:
- pass
- st = os.statvfs(path)
- else:
- raise
- free = (st.f_bavail * st.f_frsize)
- total = (st.f_blocks * st.f_frsize)
- used = (st.f_blocks - st.f_bfree) * st.f_frsize
- percent = usage_percent(used, total, _round=1)
- # NB: the percentage is -5% than what shown by df due to
- # reserved blocks that we are currently not considering:
- # http://goo.gl/sWGbH
- return sdiskusage(total, used, free, percent)
-
-
-@memoize
-def _get_terminal_map():
- ret = {}
- ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
- for name in ls:
- assert name not in ret
- try:
- ret[os.stat(name).st_rdev] = name
- except OSError as err:
- if err.errno != errno.ENOENT:
- raise
- return ret
diff --git a/python/psutil/psutil/_pssunos.py b/python/psutil/psutil/_pssunos.py
deleted file mode 100644
index bc35a718c..000000000
--- a/python/psutil/psutil/_pssunos.py
+++ /dev/null
@@ -1,553 +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.
-
-"""Sun OS Solaris platform implementation."""
-
-import errno
-import os
-import socket
-import subprocess
-import sys
-from collections import namedtuple
-
-from . import _common
-from . import _psposix
-from . import _psutil_posix as cext_posix
-from . import _psutil_sunos as cext
-from ._common import isfile_strict, socktype_to_enum, sockfam_to_enum
-from ._common import usage_percent
-from ._compat import PY3
-
-
-__extra__all__ = ["CONN_IDLE", "CONN_BOUND"]
-
-PAGE_SIZE = os.sysconf('SC_PAGE_SIZE')
-AF_LINK = cext_posix.AF_LINK
-
-CONN_IDLE = "IDLE"
-CONN_BOUND = "BOUND"
-
-PROC_STATUSES = {
- cext.SSLEEP: _common.STATUS_SLEEPING,
- cext.SRUN: _common.STATUS_RUNNING,
- cext.SZOMB: _common.STATUS_ZOMBIE,
- cext.SSTOP: _common.STATUS_STOPPED,
- cext.SIDL: _common.STATUS_IDLE,
- cext.SONPROC: _common.STATUS_RUNNING, # same as run
- cext.SWAIT: _common.STATUS_WAITING,
-}
-
-TCP_STATUSES = {
- cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
- cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
- cext.TCPS_SYN_RCVD: _common.CONN_SYN_RECV,
- cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
- cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
- cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
- cext.TCPS_CLOSED: _common.CONN_CLOSE,
- cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
- cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
- cext.TCPS_LISTEN: _common.CONN_LISTEN,
- cext.TCPS_CLOSING: _common.CONN_CLOSING,
- cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
- cext.TCPS_IDLE: CONN_IDLE, # sunos specific
- cext.TCPS_BOUND: CONN_BOUND, # sunos specific
-}
-
-scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait'])
-svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
-pextmem = namedtuple('pextmem', ['rss', 'vms'])
-pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss', 'anon', 'locked'])
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-
-# set later from __init__.py
-NoSuchProcess = None
-ZombieProcess = None
-AccessDenied = None
-TimeoutExpired = None
-
-# --- functions
-
-disk_io_counters = cext.disk_io_counters
-net_io_counters = cext.net_io_counters
-disk_usage = _psposix.disk_usage
-net_if_addrs = cext_posix.net_if_addrs
-
-
-def virtual_memory():
- # we could have done this with kstat, but imho this is good enough
- total = os.sysconf('SC_PHYS_PAGES') * PAGE_SIZE
- # note: there's no difference on Solaris
- free = avail = os.sysconf('SC_AVPHYS_PAGES') * PAGE_SIZE
- used = total - free
- percent = usage_percent(used, total, _round=1)
- return svmem(total, avail, percent, used, free)
-
-
-def swap_memory():
- sin, sout = cext.swap_mem()
- # XXX
- # we are supposed to get total/free by doing so:
- # http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/
- # usr/src/cmd/swap/swap.c
- # ...nevertheless I can't manage to obtain the same numbers as 'swap'
- # cmdline utility, so let's parse its output (sigh!)
- p = subprocess.Popen(['/usr/bin/env', 'PATH=/usr/sbin:/sbin:%s' %
- os.environ['PATH'], 'swap', '-l', '-k'],
- stdout=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if PY3:
- stdout = stdout.decode(sys.stdout.encoding)
- if p.returncode != 0:
- raise RuntimeError("'swap -l -k' failed (retcode=%s)" % p.returncode)
-
- lines = stdout.strip().split('\n')[1:]
- if not lines:
- raise RuntimeError('no swap device(s) configured')
- total = free = 0
- for line in lines:
- line = line.split()
- t, f = line[-2:]
- t = t.replace('K', '')
- f = f.replace('K', '')
- total += int(int(t) * 1024)
- free += int(int(f) * 1024)
- used = total - free
- percent = usage_percent(used, total, _round=1)
- return _common.sswap(total, used, free, percent,
- sin * PAGE_SIZE, sout * PAGE_SIZE)
-
-
-def pids():
- """Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir('/proc') if x.isdigit()]
-
-
-def pid_exists(pid):
- """Check for the existence of a unix pid."""
- return _psposix.pid_exists(pid)
-
-
-def cpu_times():
- """Return system-wide CPU times as a named tuple"""
- ret = cext.per_cpu_times()
- return scputimes(*[sum(x) for x in zip(*ret)])
-
-
-def per_cpu_times():
- """Return system per-CPU times as a list of named tuples"""
- ret = cext.per_cpu_times()
- return [scputimes(*x) for x in ret]
-
-
-def cpu_count_logical():
- """Return the number of logical CPUs in the system."""
- try:
- return os.sysconf("SC_NPROCESSORS_ONLN")
- except ValueError:
- # mimic os.cpu_count() behavior
- return None
-
-
-def cpu_count_physical():
- """Return the number of physical CPUs in the system."""
- return cext.cpu_count_phys()
-
-
-def boot_time():
- """The system boot time expressed in seconds since the epoch."""
- return cext.boot_time()
-
-
-def users():
- """Return currently connected users as a list of namedtuples."""
- retlist = []
- rawlist = cext.users()
- localhost = (':0.0', ':0')
- for item in rawlist:
- user, tty, hostname, tstamp, user_process = item
- # note: the underlying C function includes entries about
- # system boot, run level and others. We might want
- # to use them in the future.
- if not user_process:
- continue
- if hostname in localhost:
- hostname = 'localhost'
- nt = _common.suser(user, tty, hostname, tstamp)
- retlist.append(nt)
- return retlist
-
-
-def disk_partitions(all=False):
- """Return system disk partitions."""
- # TODO - the filtering logic should be better checked so that
- # it tries to reflect 'df' as much as possible
- retlist = []
- partitions = cext.disk_partitions()
- for partition in partitions:
- device, mountpoint, fstype, opts = partition
- if device == 'none':
- device = ''
- if not all:
- # Differently from, say, Linux, we don't have a list of
- # common fs types so the best we can do, AFAIK, is to
- # filter by filesystem having a total size > 0.
- if not disk_usage(mountpoint).total:
- continue
- ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
- retlist.append(ntuple)
- return retlist
-
-
-def net_connections(kind, _pid=-1):
- """Return socket connections. If pid == -1 return system-wide
- connections (as opposed to connections opened by one process only).
- Only INET sockets are returned (UNIX are not).
- """
- cmap = _common.conn_tmap.copy()
- if _pid == -1:
- cmap.pop('unix', 0)
- if kind not in cmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in cmap])))
- families, types = _common.conn_tmap[kind]
- rawlist = cext.net_connections(_pid, families, types)
- ret = set()
- for item in rawlist:
- fd, fam, type_, laddr, raddr, status, pid = item
- if fam not in families:
- continue
- if type_ not in types:
- continue
- status = TCP_STATUSES[status]
- fam = sockfam_to_enum(fam)
- type_ = socktype_to_enum(type_)
- if _pid == -1:
- nt = _common.sconn(fd, fam, type_, laddr, raddr, status, pid)
- else:
- nt = _common.pconn(fd, fam, type_, laddr, raddr, status)
- ret.add(nt)
- return list(ret)
-
-
-def net_if_stats():
- """Get NIC stats (isup, duplex, speed, mtu)."""
- ret = cext.net_if_stats()
- for name, items in ret.items():
- isup, duplex, speed, mtu = items
- if hasattr(_common, 'NicDuplex'):
- duplex = _common.NicDuplex(duplex)
- ret[name] = _common.snicstats(isup, duplex, speed, mtu)
- return ret
-
-
-def wrap_exceptions(fun):
- """Call callable into a try/except clause and translate ENOENT,
- EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
- """
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except EnvironmentError as err:
- # support for private module import
- if (NoSuchProcess is None or AccessDenied is None or
- ZombieProcess is None):
- raise
- # ENOENT (no such file or directory) gets raised on open().
- # ESRCH (no such process) can get raised on read() if
- # process is gone in meantime.
- if err.errno in (errno.ENOENT, errno.ESRCH):
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- if err.errno in (errno.EPERM, errno.EACCES):
- raise AccessDenied(self.pid, self._name)
- raise
- return wrapper
-
-
-class Process(object):
- """Wrapper class around underlying C implementation."""
-
- __slots__ = ["pid", "_name", "_ppid"]
-
- def __init__(self, pid):
- self.pid = pid
- self._name = None
- self._ppid = None
-
- @wrap_exceptions
- def name(self):
- # note: max len == 15
- return cext.proc_name_and_args(self.pid)[0]
-
- @wrap_exceptions
- def exe(self):
- # Will be guess later from cmdline but we want to explicitly
- # invoke cmdline here in order to get an AccessDenied
- # exception if the user has not enough privileges.
- self.cmdline()
- return ""
-
- @wrap_exceptions
- def cmdline(self):
- return cext.proc_name_and_args(self.pid)[1].split(' ')
-
- @wrap_exceptions
- def create_time(self):
- return cext.proc_basic_info(self.pid)[3]
-
- @wrap_exceptions
- def num_threads(self):
- return cext.proc_basic_info(self.pid)[5]
-
- @wrap_exceptions
- def nice_get(self):
- # For some reason getpriority(3) return ESRCH (no such process)
- # for certain low-pid processes, no matter what (even as root).
- # The process actually exists though, as it has a name,
- # creation time, etc.
- # The best thing we can do here appears to be raising AD.
- # Note: tested on Solaris 11; on Open Solaris 5 everything is
- # fine.
- try:
- return cext_posix.getpriority(self.pid)
- except EnvironmentError as err:
- # 48 is 'operation not supported' but errno does not expose
- # it. It occurs for low system pids.
- if err.errno in (errno.ENOENT, errno.ESRCH, 48):
- if pid_exists(self.pid):
- raise AccessDenied(self.pid, self._name)
- raise
-
- @wrap_exceptions
- def nice_set(self, value):
- if self.pid in (2, 3):
- # Special case PIDs: internally setpriority(3) return ESRCH
- # (no such process), no matter what.
- # The process actually exists though, as it has a name,
- # creation time, etc.
- raise AccessDenied(self.pid, self._name)
- return cext_posix.setpriority(self.pid, value)
-
- @wrap_exceptions
- def ppid(self):
- return cext.proc_basic_info(self.pid)[0]
-
- @wrap_exceptions
- def uids(self):
- real, effective, saved, _, _, _ = cext.proc_cred(self.pid)
- return _common.puids(real, effective, saved)
-
- @wrap_exceptions
- def gids(self):
- _, _, _, real, effective, saved = cext.proc_cred(self.pid)
- return _common.puids(real, effective, saved)
-
- @wrap_exceptions
- def cpu_times(self):
- user, system = cext.proc_cpu_times(self.pid)
- return _common.pcputimes(user, system)
-
- @wrap_exceptions
- def terminal(self):
- hit_enoent = False
- tty = wrap_exceptions(
- cext.proc_basic_info(self.pid)[0])
- if tty != cext.PRNODEV:
- for x in (0, 1, 2, 255):
- try:
- return os.readlink('/proc/%d/path/%d' % (self.pid, x))
- except OSError as err:
- if err.errno == errno.ENOENT:
- hit_enoent = True
- continue
- raise
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
-
- @wrap_exceptions
- def cwd(self):
- # /proc/PID/path/cwd may not be resolved by readlink() even if
- # it exists (ls shows it). If that's the case and the process
- # is still alive return None (we can return None also on BSD).
- # Reference: http://goo.gl/55XgO
- try:
- return os.readlink("/proc/%s/path/cwd" % self.pid)
- except OSError as err:
- if err.errno == errno.ENOENT:
- os.stat("/proc/%s" % self.pid)
- return None
- raise
-
- @wrap_exceptions
- def memory_info(self):
- ret = cext.proc_basic_info(self.pid)
- rss, vms = ret[1] * 1024, ret[2] * 1024
- return _common.pmem(rss, vms)
-
- # it seems Solaris uses rss and vms only
- memory_info_ex = memory_info
-
- @wrap_exceptions
- def status(self):
- code = cext.proc_basic_info(self.pid)[6]
- # XXX is '?' legit? (we're not supposed to return it anyway)
- return PROC_STATUSES.get(code, '?')
-
- @wrap_exceptions
- def threads(self):
- ret = []
- tids = os.listdir('/proc/%d/lwp' % self.pid)
- hit_enoent = False
- for tid in tids:
- tid = int(tid)
- try:
- utime, stime = cext.query_process_thread(
- self.pid, tid)
- except EnvironmentError as err:
- # ENOENT == thread gone in meantime
- if err.errno == errno.ENOENT:
- hit_enoent = True
- continue
- raise
- else:
- nt = _common.pthread(tid, utime, stime)
- ret.append(nt)
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return ret
-
- @wrap_exceptions
- def open_files(self):
- retlist = []
- hit_enoent = False
- pathdir = '/proc/%d/path' % self.pid
- for fd in os.listdir('/proc/%d/fd' % self.pid):
- path = os.path.join(pathdir, fd)
- if os.path.islink(path):
- try:
- file = os.readlink(path)
- except OSError as err:
- # ENOENT == file which is gone in the meantime
- if err.errno == errno.ENOENT:
- hit_enoent = True
- continue
- raise
- else:
- if isfile_strict(file):
- retlist.append(_common.popenfile(file, int(fd)))
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return retlist
-
- def _get_unix_sockets(self, pid):
- """Get UNIX sockets used by process by parsing 'pfiles' output."""
- # TODO: rewrite this in C (...but the damn netstat source code
- # does not include this part! Argh!!)
- cmd = "pfiles %s" % pid
- p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = [x.decode(sys.stdout.encoding)
- for x in (stdout, stderr)]
- if p.returncode != 0:
- if 'permission denied' in stderr.lower():
- raise AccessDenied(self.pid, self._name)
- if 'no such process' in stderr.lower():
- raise NoSuchProcess(self.pid, self._name)
- raise RuntimeError("%r command error\n%s" % (cmd, stderr))
-
- lines = stdout.split('\n')[2:]
- for i, line in enumerate(lines):
- line = line.lstrip()
- if line.startswith('sockname: AF_UNIX'):
- path = line.split(' ', 2)[2]
- type = lines[i - 2].strip()
- if type == 'SOCK_STREAM':
- type = socket.SOCK_STREAM
- elif type == 'SOCK_DGRAM':
- type = socket.SOCK_DGRAM
- else:
- type = -1
- yield (-1, socket.AF_UNIX, type, path, "", _common.CONN_NONE)
-
- @wrap_exceptions
- def connections(self, kind='inet'):
- ret = net_connections(kind, _pid=self.pid)
- # The underlying C implementation retrieves all OS connections
- # and filters them by PID. At this point we can't tell whether
- # an empty list means there were no connections for process or
- # process is no longer active so we force NSP in case the PID
- # is no longer there.
- if not ret:
- os.stat('/proc/%s' % self.pid) # will raise NSP if process is gone
-
- # UNIX sockets
- if kind in ('all', 'unix'):
- ret.extend([_common.pconn(*conn) for conn in
- self._get_unix_sockets(self.pid)])
- return ret
-
- nt_mmap_grouped = namedtuple('mmap', 'path rss anon locked')
- nt_mmap_ext = namedtuple('mmap', 'addr perms path rss anon locked')
-
- @wrap_exceptions
- def memory_maps(self):
- def toaddr(start, end):
- return '%s-%s' % (hex(start)[2:].strip('L'),
- hex(end)[2:].strip('L'))
-
- retlist = []
- rawlist = cext.proc_memory_maps(self.pid)
- hit_enoent = False
- for item in rawlist:
- addr, addrsize, perm, name, rss, anon, locked = item
- addr = toaddr(addr, addrsize)
- if not name.startswith('['):
- try:
- name = os.readlink('/proc/%s/path/%s' % (self.pid, name))
- except OSError as err:
- if err.errno == errno.ENOENT:
- # sometimes the link may not be resolved by
- # readlink() even if it exists (ls shows it).
- # If that's the case we just return the
- # unresolved link path.
- # This seems an incosistency with /proc similar
- # to: http://goo.gl/55XgO
- name = '/proc/%s/path/%s' % (self.pid, name)
- hit_enoent = True
- else:
- raise
- retlist.append((addr, perm, name, rss, anon, locked))
- if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('/proc/%s' % self.pid)
- return retlist
-
- @wrap_exceptions
- def num_fds(self):
- return len(os.listdir("/proc/%s/fd" % self.pid))
-
- @wrap_exceptions
- def num_ctx_switches(self):
- return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
-
- @wrap_exceptions
- def wait(self, timeout=None):
- try:
- return _psposix.wait_pid(self.pid, timeout)
- except _psposix.TimeoutExpired:
- # support for private module import
- if TimeoutExpired is None:
- raise
- raise TimeoutExpired(timeout, self.pid, self._name)
diff --git a/python/psutil/psutil/_psutil_bsd.c b/python/psutil/psutil/_psutil_bsd.c
deleted file mode 100644
index 7b6e56173..000000000
--- a/python/psutil/psutil/_psutil_bsd.c
+++ /dev/null
@@ -1,2296 +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.
- *
- * FreeBSD platform-specific module methods for _psutil_bsd
- */
-
-
-#include <Python.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <paths.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <sys/param.h>
-#include <sys/user.h>
-#include <sys/proc.h>
-#include <sys/file.h>
-#include <sys/cpuset.h>
-#include <net/route.h>
-
-#include <sys/socket.h>
-#include <sys/socketvar.h> // for struct xsocket
-#include <sys/un.h>
-#include <sys/unpcb.h>
-#include <sys/sockio.h>
-// for xinpcb struct
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/in_pcb.h>
-#include <netinet/tcp_var.h> // for struct xtcpcb
-#include <netinet/tcp_fsm.h> // for TCP connection states
-#include <arpa/inet.h> // for inet_ntop()
-
-#if __FreeBSD_version < 900000
-#include <utmp.h> // system users
-#else
-#include <utmpx.h>
-#endif
-#include <devstat.h> // get io counters
-#include <sys/vmmeter.h> // needed for vmtotal struct
-#include <libutil.h> // process open files, shared libs (kinfo_getvmmap)
-#include <sys/mount.h>
-
-#include <net/if.h> // net io counters
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <net/if_media.h>
-
-#include <netinet/in.h> // process open files/connections
-#include <sys/un.h>
-
-#include "_psutil_bsd.h"
-#include "_psutil_common.h"
-#include "arch/bsd/process_info.h"
-
-
-// convert a timeval struct to a double
-#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
-
-
-/*
- * Utility function which fills a kinfo_proc struct based on process pid
- */
-static int
-psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
-{
- int mib[4];
- size_t size;
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = pid;
-
- size = sizeof(struct kinfo_proc);
-
- if (sysctl((int *)mib, 4, proc, &size, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return -1;
- }
-
- // sysctl stores 0 in the size if we can't find the process information.
- if (size == 0) {
- NoSuchProcess();
- return -1;
- }
- return 0;
-}
-
-
-/*
- * Set exception to AccessDenied if pid exists else NoSuchProcess.
- */
-void
-psutil_raise_ad_or_nsp(long pid) {
- if (psutil_pid_exists(pid) == 0)
- NoSuchProcess();
- else
- AccessDenied();
-}
-
-
-/*
- * Return a Python list of all the PIDs running on the system.
- */
-static PyObject *
-psutil_pids(PyObject *self, PyObject *args)
-{
- kinfo_proc *proclist = NULL;
- kinfo_proc *orig_address = NULL;
- size_t num_processes;
- size_t idx;
- PyObject *retlist = PyList_New(0);
- PyObject *pid = NULL;
-
- if (retlist == NULL)
- return NULL;
- if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
- PyErr_SetString(PyExc_RuntimeError,
- "failed to retrieve process list.");
- goto error;
- }
-
- if (num_processes > 0) {
- orig_address = proclist; // save so we can free it after we're done
- for (idx = 0; idx < num_processes; idx++) {
- pid = Py_BuildValue("i", proclist->ki_pid);
- if (!pid)
- goto error;
- if (PyList_Append(retlist, pid))
- goto error;
- Py_DECREF(pid);
- proclist++;
- }
- free(orig_address);
- }
-
- return retlist;
-
-error:
- Py_XDECREF(pid);
- Py_DECREF(retlist);
- if (orig_address != NULL)
- free(orig_address);
- return NULL;
-}
-
-
-/*
- * Return a Python float indicating the system boot time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_boot_time(PyObject *self, PyObject *args)
-{
- // fetch sysctl "kern.boottime"
- static int request[2] = { CTL_KERN, KERN_BOOTTIME };
- struct timeval boottime;
- size_t len = sizeof(boottime);
-
- if (sysctl(request, 2, &boottime, &len, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
- return Py_BuildValue("d", (double)boottime.tv_sec);
-}
-
-
-/*
- * Return process name from kinfo_proc as a Python string.
- */
-static PyObject *
-psutil_proc_name(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("s", kp.ki_comm);
-}
-
-
-/*
- * Return process pathname executable.
- * Thanks to Robert N. M. Watson:
- * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_bin.c?v=8-CURRENT
- */
-static PyObject *
-psutil_proc_exe(PyObject *self, PyObject *args)
-{
- long pid;
- char pathname[PATH_MAX];
- int error;
- int mib[4];
- size_t size;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PATHNAME;
- mib[3] = pid;
-
- size = sizeof(pathname);
- error = sysctl(mib, 4, pathname, &size, NULL, 0);
- if (error == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
- if (size == 0 || strlen(pathname) == 0) {
- if (psutil_pid_exists(pid) == 0)
- return NoSuchProcess();
- else
- strcpy(pathname, "");
- }
- return Py_BuildValue("s", pathname);
-}
-
-
-/*
- * Return process cmdline as a Python list of cmdline arguments.
- */
-static PyObject *
-psutil_proc_cmdline(PyObject *self, PyObject *args)
-{
- long pid;
- PyObject *arglist = NULL;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- // get the commandline, defined in arch/bsd/process_info.c
- arglist = psutil_get_arg_list(pid);
-
- // psutil_get_arg_list() returns NULL only if psutil_cmd_args
- // failed with ESRCH (no process with that PID)
- if (NULL == arglist)
- return PyErr_SetFromErrno(PyExc_OSError);
- return Py_BuildValue("N", arglist);
-}
-
-
-/*
- * Return process parent pid from kinfo_proc as a Python integer.
- */
-static PyObject *
-psutil_proc_ppid(PyObject *self, PyObject *args)
-{
- long pid;
- struct 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.ki_ppid);
-}
-
-
-/*
- * Return process status as a Python integer.
- */
-static PyObject *
-psutil_proc_status(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("i", (int)kp.ki_stat);
-}
-
-
-/*
- * Return process real, effective and saved user ids from kinfo_proc
- * as a Python tuple.
- */
-static PyObject *
-psutil_proc_uids(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("lll",
- (long)kp.ki_ruid,
- (long)kp.ki_uid,
- (long)kp.ki_svuid);
-}
-
-
-/*
- * Return process real, effective and saved group ids from kinfo_proc
- * as a Python tuple.
- */
-static PyObject *
-psutil_proc_gids(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("lll",
- (long)kp.ki_rgid,
- (long)kp.ki_groups[0],
- (long)kp.ki_svuid);
-}
-
-
-/*
- * Return process real, effective and saved group ids from kinfo_proc
- * as a Python tuple.
- */
-static PyObject *
-psutil_proc_tty_nr(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("i", kp.ki_tdev);
-}
-
-
-/*
- * Return the number of context switches performed by process as a tuple.
- */
-static PyObject *
-psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("(ll)",
- kp.ki_rusage.ru_nvcsw,
- kp.ki_rusage.ru_nivcsw);
-}
-
-
-/*
- * Return number of threads used by process as a Python integer.
- */
-static PyObject *
-psutil_proc_num_threads(PyObject *self, PyObject *args)
-{
- long pid;
- struct 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.ki_numthreads);
-}
-
-
-/*
- * Retrieves all threads used by process returning a list of tuples
- * including thread id, user time and system time.
- * Thanks to Robert N. M. Watson:
- * http://fxr.googlebit.com/source/usr.bin/procstat/
- * procstat_threads.c?v=8-CURRENT
- */
-static PyObject *
-psutil_proc_threads(PyObject *self, PyObject *args)
-{
- long pid;
- int mib[4];
- struct kinfo_proc *kip = NULL;
- struct kinfo_proc *kipp = NULL;
- int error;
- unsigned int i;
- size_t size;
- PyObject *retList = PyList_New(0);
- PyObject *pyTuple = NULL;
-
- if (retList == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
-
- // we need to re-query for thread information, so don't use *kipp
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
- mib[3] = pid;
-
- size = 0;
- error = sysctl(mib, 4, NULL, &size, NULL, 0);
- if (error == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- if (size == 0) {
- NoSuchProcess();
- goto error;
- }
-
- kip = malloc(size);
- if (kip == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- error = sysctl(mib, 4, kip, &size, NULL, 0);
- if (error == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- if (size == 0) {
- NoSuchProcess();
- goto error;
- }
-
- for (i = 0; i < size / sizeof(*kipp); i++) {
- kipp = &kip[i];
- pyTuple = Py_BuildValue("Idd",
- kipp->ki_tid,
- TV2DOUBLE(kipp->ki_rusage.ru_utime),
- TV2DOUBLE(kipp->ki_rusage.ru_stime));
- if (pyTuple == NULL)
- goto error;
- if (PyList_Append(retList, pyTuple))
- goto error;
- Py_DECREF(pyTuple);
- }
- free(kip);
- return retList;
-
-error:
- Py_XDECREF(pyTuple);
- Py_DECREF(retList);
- if (kip != NULL)
- free(kip);
- return NULL;
-}
-
-
-/*
- * Return a Python tuple (user_time, kernel_time)
- */
-static PyObject *
-psutil_proc_cpu_times(PyObject *self, PyObject *args)
-{
- long pid;
- double user_t, sys_t;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- // convert from microseconds to seconds
- user_t = TV2DOUBLE(kp.ki_rusage.ru_utime);
- sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime);
- return Py_BuildValue("(dd)", user_t, sys_t);
-}
-
-
-/*
- * Return the number of logical CPUs in the system.
- * XXX this could be shared with OSX
- */
-static PyObject *
-psutil_cpu_count_logical(PyObject *self, PyObject *args)
-{
- int mib[2];
- int ncpu;
- size_t len;
-
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(ncpu);
-
- if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", ncpu);
-}
-
-
-/*
- * Return an XML string from which we'll determine the number of
- * physical CPU cores in the system.
- */
-static PyObject *
-psutil_cpu_count_phys(PyObject *self, PyObject *args)
-{
- void *topology = NULL;
- size_t size = 0;
- PyObject *py_str;
-
- if (sysctlbyname("kern.sched.topology_spec", NULL, &size, NULL, 0))
- goto error;
-
- topology = malloc(size);
- if (!topology) {
- PyErr_NoMemory();
- return NULL;
- }
-
- if (sysctlbyname("kern.sched.topology_spec", topology, &size, NULL, 0))
- goto error;
-
- py_str = Py_BuildValue("s", topology);
- free(topology);
- return py_str;
-
-error:
- if (topology != NULL)
- free(topology);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Return a Python float indicating the process create time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_proc_create_time(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("d", TV2DOUBLE(kp.ki_start));
-}
-
-
-/*
- * Return a Python float indicating the process create time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_proc_io_counters(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- // there's apparently no way to determine bytes count, hence return -1.
- return Py_BuildValue("(llll)",
- kp.ki_rusage.ru_inblock,
- kp.ki_rusage.ru_oublock,
- -1,
- -1);
-}
-
-
-/*
- * Return extended memory info for a process as a Python tuple.
- */
-static PyObject *
-psutil_proc_memory_info(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("(lllll)",
- ptoa(kp.ki_rssize), // rss
- (long)kp.ki_size, // vms
- ptoa(kp.ki_tsize), // text
- ptoa(kp.ki_dsize), // data
- ptoa(kp.ki_ssize)); // stack
-}
-
-
-/*
- * Return virtual memory usage statistics.
- */
-static PyObject *
-psutil_virtual_mem(PyObject *self, PyObject *args)
-{
- unsigned int total, active, inactive, wired, cached, free;
- size_t size = sizeof(total);
- struct vmtotal vm;
- int mib[] = {CTL_VM, VM_METER};
- long pagesize = getpagesize();
-#if __FreeBSD_version > 702101
- long buffers;
-#else
- int buffers;
-#endif
- size_t buffers_size = sizeof(buffers);
-
- if (sysctlbyname("vm.stats.vm.v_page_count", &total, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vm.stats.vm.v_active_count", &active, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vm.stats.vm.v_inactive_count",
- &inactive, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vm.stats.vm.v_wire_count", &wired, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vm.stats.vm.v_cache_count", &cached, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vm.stats.vm.v_free_count", &free, &size, NULL, 0))
- goto error;
- if (sysctlbyname("vfs.bufspace", &buffers, &buffers_size, NULL, 0))
- goto error;
-
- size = sizeof(vm);
- if (sysctl(mib, 2, &vm, &size, NULL, 0) != 0)
- goto error;
-
- return Py_BuildValue("KKKKKKKK",
- (unsigned long long) total * pagesize,
- (unsigned long long) free * pagesize,
- (unsigned long long) active * pagesize,
- (unsigned long long) inactive * pagesize,
- (unsigned long long) wired * pagesize,
- (unsigned long long) cached * pagesize,
- (unsigned long long) buffers,
- (unsigned long long) (vm.t_vmshr + vm.t_rmshr) * pagesize // shared
- );
-
-error:
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
-}
-
-
-#ifndef _PATH_DEVNULL
-#define _PATH_DEVNULL "/dev/null"
-#endif
-
-/*
- * Return swap memory stats (see 'swapinfo' cmdline tool)
- */
-static PyObject *
-psutil_swap_mem(PyObject *self, PyObject *args)
-{
- kvm_t *kd;
- struct kvm_swap kvmsw[1];
- unsigned int swapin, swapout, nodein, nodeout;
- size_t size = sizeof(unsigned int);
-
- kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open failed");
- if (kd == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "kvm_open failed");
- return NULL;
- }
-
- if (kvm_getswapinfo(kd, kvmsw, 1, 0) < 0) {
- kvm_close(kd);
- PyErr_SetString(PyExc_RuntimeError, "kvm_getswapinfo failed");
- return NULL;
- }
-
- kvm_close(kd);
-
- if (sysctlbyname("vm.stats.vm.v_swapin", &swapin, &size, NULL, 0) == -1)
- goto sbn_error;
- if (sysctlbyname("vm.stats.vm.v_swapout", &swapout, &size, NULL, 0) == -1)
- goto sbn_error;
- if (sysctlbyname("vm.stats.vm.v_vnodein", &nodein, &size, NULL, 0) == -1)
- goto sbn_error;
- if (sysctlbyname("vm.stats.vm.v_vnodeout", &nodeout, &size, NULL, 0) == -1)
- goto sbn_error;
-
- return Py_BuildValue("(iiiII)",
- kvmsw[0].ksw_total, // total
- kvmsw[0].ksw_used, // used
- kvmsw[0].ksw_total - kvmsw[0].ksw_used, // free
- swapin + swapout, // swap in
- nodein + nodeout); // swap out
-
-sbn_error:
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
-}
-
-
-/*
- * Return a Python tuple representing user, kernel and idle CPU times
- */
-static PyObject *
-psutil_cpu_times(PyObject *self, PyObject *args)
-{
- long cpu_time[CPUSTATES];
- size_t size;
-
- size = sizeof(cpu_time);
-
- if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
-
- return Py_BuildValue("(ddddd)",
- (double)cpu_time[CP_USER] / CLOCKS_PER_SEC,
- (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC,
- (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC,
- (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC,
- (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC
- );
-}
-
-
-/*
- * XXX
- * These functions are available on FreeBSD 8 only.
- * In the upper python layer we do various tricks to avoid crashing
- * and/or to provide alternatives where possible.
- */
-
-
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
-/*
- * Return files opened by process as a list of (path, fd) tuples.
- * TODO: this is broken as it may report empty paths. 'procstat'
- * utility has the same problem see:
- * https://github.com/giampaolo/psutil/issues/595
- */
-static PyObject *
-psutil_proc_open_files(PyObject *self, PyObject *args)
-{
- long pid;
- int i, cnt;
- struct kinfo_file *freep = NULL;
- struct kinfo_file *kif;
- struct kinfo_proc kipp;
- PyObject *retList = PyList_New(0);
- PyObject *tuple = NULL;
-
- if (retList == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
- if (psutil_kinfo_proc(pid, &kipp) == -1)
- goto error;
-
- freep = kinfo_getfile(pid, &cnt);
- if (freep == NULL) {
- psutil_raise_ad_or_nsp(pid);
- goto error;
- }
-
- for (i = 0; i < cnt; i++) {
- kif = &freep[i];
- if ((kif->kf_type == KF_TYPE_VNODE) &&
- (kif->kf_vnode_type == KF_VTYPE_VREG))
- {
- tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd);
- if (tuple == NULL)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- }
- free(freep);
- return retList;
-
-error:
- Py_XDECREF(tuple);
- Py_DECREF(retList);
- if (freep != NULL)
- free(freep);
- return NULL;
-}
-
-
-/*
- * Return files opened by process as a list of (path, fd) tuples
- */
-static 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;
-
- freep = kinfo_getfile(pid, &cnt);
- if (freep == NULL) {
- psutil_raise_ad_or_nsp(pid);
- return NULL;
- }
- free(freep);
-
- return Py_BuildValue("i", cnt);
-}
-
-
-/*
- * Return process current working directory.
- */
-static PyObject *
-psutil_proc_cwd(PyObject *self, PyObject *args)
-{
- long pid;
- PyObject *path = NULL;
- struct kinfo_file *freep = NULL;
- struct kinfo_file *kif;
- struct kinfo_proc kipp;
-
- int i, cnt;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
- if (psutil_kinfo_proc(pid, &kipp) == -1)
- goto error;
-
- freep = kinfo_getfile(pid, &cnt);
- if (freep == NULL) {
- psutil_raise_ad_or_nsp(pid);
- goto error;
- }
-
- for (i = 0; i < cnt; i++) {
- kif = &freep[i];
- if (kif->kf_fd == KF_FD_TYPE_CWD) {
- path = Py_BuildValue("s", kif->kf_path);
- if (!path)
- goto error;
- break;
- }
- }
- /*
- * For lower pids it seems we can't retrieve any information
- * (lsof can't do that it either). Since this happens even
- * as root we return an empty string instead of AccessDenied.
- */
- if (path == NULL)
- path = Py_BuildValue("s", "");
- free(freep);
- return path;
-
-error:
- Py_XDECREF(path);
- if (freep != NULL)
- free(freep);
- return NULL;
-}
-
-
-// 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);
-}
-
-static struct tcpcb *
-psutil_search_tcplist(char *buf, struct kinfo_file *kif)
-{
- struct tcpcb *tp;
- struct inpcb *inp;
- 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)) {
- tp = &((struct xtcpcb *)xig)->xt_tp;
- inp = &((struct xtcpcb *)xig)->xt_inp;
- so = &((struct xtcpcb *)xig)->xt_socket;
-
- if (so->so_type != kif->kf_sock_type ||
- so->xso_family != kif->kf_sock_domain ||
- so->xso_protocol != kif->kf_sock_protocol)
- continue;
-
- if (kif->kf_sock_domain == AF_INET) {
- if (!psutil_sockaddr_matches(
- AF_INET, inp->inp_lport, &inp->inp_laddr,
- &kif->kf_sa_local))
- continue;
- if (!psutil_sockaddr_matches(
- AF_INET, inp->inp_fport, &inp->inp_faddr,
- &kif->kf_sa_peer))
- continue;
- } else {
- if (!psutil_sockaddr_matches(
- AF_INET6, inp->inp_lport, &inp->in6p_laddr,
- &kif->kf_sa_local))
- continue;
- if (!psutil_sockaddr_matches(
- AF_INET6, inp->inp_fport, &inp->in6p_faddr,
- &kif->kf_sa_peer))
- continue;
- }
-
- return (tp);
- }
- return NULL;
-}
-
-
-// a signaler for connections without an actual status
-static int PSUTIL_CONN_NONE = 128;
-
-/*
- * Return connections opened by process.
- */
-static PyObject *
-psutil_proc_connections(PyObject *self, PyObject *args)
-{
- long pid;
- int i, cnt;
-
- struct kinfo_file *freep = NULL;
- struct kinfo_file *kif;
- char *tcplist = NULL;
- struct tcpcb *tcp;
-
- PyObject *retList = PyList_New(0);
- PyObject *tuple = NULL;
- PyObject *laddr = NULL;
- PyObject *raddr = NULL;
- PyObject *af_filter = NULL;
- PyObject *type_filter = NULL;
- PyObject *_family = NULL;
- PyObject *_type = NULL;
-
- if (retList == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
- goto error;
- if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
- PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
- goto error;
- }
-
- freep = kinfo_getfile(pid, &cnt);
- if (freep == NULL) {
- psutil_raise_ad_or_nsp(pid);
- 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;
- tuple = NULL;
- laddr = NULL;
- raddr = NULL;
-
- kif = &freep[i];
- if (kif->kf_type == KF_TYPE_SOCKET) {
- // apply filters
- _family = PyLong_FromLong((long)kif->kf_sock_domain);
- inseq = PySequence_Contains(af_filter, _family);
- Py_DECREF(_family);
- if (inseq == 0)
- continue;
- _type = PyLong_FromLong((long)kif->kf_sock_type);
- inseq = PySequence_Contains(type_filter, _type);
- Py_DECREF(_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,
- &kif->kf_sa_local),
- lip,
- sizeof(lip));
- inet_ntop(
- kif->kf_sock_domain,
- psutil_sockaddr_addr(kif->kf_sock_domain,
- &kif->kf_sa_peer),
- rip,
- sizeof(rip));
- lport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
- &kif->kf_sa_local));
- rport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
- &kif->kf_sa_peer));
-
- // construct python tuple/list
- laddr = Py_BuildValue("(si)", lip, lport);
- if (!laddr)
- goto error;
- if (rport != 0)
- raddr = Py_BuildValue("(si)", rip, rport);
- else
- raddr = Py_BuildValue("()");
- if (!raddr)
- goto error;
- tuple = Py_BuildValue("(iiiNNi)",
- kif->kf_fd,
- kif->kf_sock_domain,
- kif->kf_sock_type,
- laddr,
- raddr,
- state);
- if (!tuple)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- // UNIX socket
- else if (kif->kf_sock_domain == AF_UNIX) {
- struct sockaddr_un *sun;
-
- sun = (struct sockaddr_un *)&kif->kf_sa_local;
- snprintf(
- path, sizeof(path), "%.*s",
- (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
- sun->sun_path);
-
- tuple = Py_BuildValue("(iiisOi)",
- kif->kf_fd,
- kif->kf_sock_domain,
- kif->kf_sock_type,
- path,
- Py_None,
- PSUTIL_CONN_NONE);
- if (!tuple)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- Py_INCREF(Py_None);
- }
- }
- }
- free(freep);
- free(tcplist);
- return retList;
-
-error:
- Py_XDECREF(tuple);
- Py_XDECREF(laddr);
- Py_XDECREF(raddr);
- Py_DECREF(retList);
- if (freep != NULL)
- free(freep);
- if (tcplist != NULL)
- free(tcplist);
- return NULL;
-}
-
-
-/*
- * Return a Python list of tuple representing per-cpu times
- */
-static PyObject *
-psutil_per_cpu_times(PyObject *self, PyObject *args)
-{
- static int maxcpus;
- int mib[2];
- int ncpu;
- size_t len;
- size_t size;
- int i;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_cputime = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- // retrieve maxcpus value
- size = sizeof(maxcpus);
- if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
- Py_DECREF(py_retlist);
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
- long cpu_time[maxcpus][CPUSTATES];
-
- // retrieve the number of cpus
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(ncpu);
- if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- // per-cpu info
- size = sizeof(cpu_time);
- if (sysctlbyname("kern.cp_times", &cpu_time, &size, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- for (i = 0; i < ncpu; i++) {
- py_cputime = Py_BuildValue(
- "(ddddd)",
- (double)cpu_time[i][CP_USER] / CLOCKS_PER_SEC,
- (double)cpu_time[i][CP_NICE] / CLOCKS_PER_SEC,
- (double)cpu_time[i][CP_SYS] / CLOCKS_PER_SEC,
- (double)cpu_time[i][CP_IDLE] / CLOCKS_PER_SEC,
- (double)cpu_time[i][CP_INTR] / CLOCKS_PER_SEC);
- 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;
-}
-
-
-// remove spaces from string
-void remove_spaces(char *str) {
- char *p1 = str;
- char *p2 = str;
- do
- while (*p2 == ' ')
- p2++;
- while ((*p1++ = *p2++));
-}
-
-
-/*
- * Return a list of tuples for every process memory maps.
- * 'procstat' cmdline utility has been used as an example.
- */
-static PyObject *
-psutil_proc_memory_maps(PyObject *self, PyObject *args)
-{
- long pid;
- int ptrwidth;
- int i, cnt;
- char addr[1000];
- char perms[4];
- const char *path;
- struct kinfo_proc kp;
- struct kinfo_vmentry *freep = NULL;
- struct kinfo_vmentry *kve;
- ptrwidth = 2 * sizeof(void *);
- PyObject *pytuple = NULL;
- PyObject *retlist = PyList_New(0);
-
- if (retlist == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
- if (psutil_kinfo_proc(pid, &kp) == -1)
- goto error;
-
- freep = kinfo_getvmmap(pid, &cnt);
- if (freep == NULL) {
- psutil_raise_ad_or_nsp(pid);
- goto error;
- }
- for (i = 0; i < cnt; i++) {
- pytuple = NULL;
- kve = &freep[i];
- addr[0] = '\0';
- perms[0] = '\0';
- sprintf(addr, "%#*jx-%#*jx", ptrwidth, (uintmax_t)kve->kve_start,
- ptrwidth, (uintmax_t)kve->kve_end);
- remove_spaces(addr);
- strlcat(perms, kve->kve_protection & KVME_PROT_READ ? "r" : "-",
- sizeof(perms));
- strlcat(perms, kve->kve_protection & KVME_PROT_WRITE ? "w" : "-",
- sizeof(perms));
- strlcat(perms, kve->kve_protection & KVME_PROT_EXEC ? "x" : "-",
- sizeof(perms));
-
- if (strlen(kve->kve_path) == 0) {
- switch (kve->kve_type) {
- case KVME_TYPE_NONE:
- path = "[none]";
- break;
- case KVME_TYPE_DEFAULT:
- path = "[default]";
- break;
- case KVME_TYPE_VNODE:
- path = "[vnode]";
- break;
- case KVME_TYPE_SWAP:
- path = "[swap]";
- break;
- case KVME_TYPE_DEVICE:
- path = "[device]";
- break;
- case KVME_TYPE_PHYS:
- path = "[phys]";
- break;
- case KVME_TYPE_DEAD:
- path = "[dead]";
- break;
- case KVME_TYPE_SG:
- path = "[sg]";
- break;
- case KVME_TYPE_UNKNOWN:
- path = "[unknown]";
- break;
- default:
- path = "[?]";
- break;
- }
- }
- else {
- path = kve->kve_path;
- }
-
- pytuple = Py_BuildValue("sssiiii",
- addr, // "start-end" address
- perms, // "rwx" permissions
- path, // path
- kve->kve_resident, // rss
- kve->kve_private_resident, // private
- kve->kve_ref_count, // ref count
- kve->kve_shadow_count); // shadow count
- if (!pytuple)
- goto error;
- if (PyList_Append(retlist, pytuple))
- goto error;
- Py_DECREF(pytuple);
- }
- free(freep);
- return retlist;
-
-error:
- Py_XDECREF(pytuple);
- Py_DECREF(retlist);
- if (freep != NULL)
- free(freep);
- return NULL;
-}
-#endif
-
-
-/*
- * Return a list of tuples including device, mount point and fs type
- * for all partitions mounted on the system.
- */
-static PyObject *
-psutil_disk_partitions(PyObject *self, PyObject *args)
-{
- int num;
- int i;
- long len;
- uint64_t flags;
- char opts[200];
- struct statfs *fs = NULL;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- // get the number of mount points
- Py_BEGIN_ALLOW_THREADS
- num = getfsstat(NULL, 0, MNT_NOWAIT);
- Py_END_ALLOW_THREADS
- if (num == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- len = sizeof(*fs) * num;
- fs = malloc(len);
- if (fs == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- Py_BEGIN_ALLOW_THREADS
- num = getfsstat(fs, len, MNT_NOWAIT);
- Py_END_ALLOW_THREADS
- if (num == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- for (i = 0; i < num; i++) {
- py_tuple = NULL;
- opts[0] = 0;
- flags = fs[i].f_flags;
-
- // see sys/mount.h
- if (flags & MNT_RDONLY)
- strlcat(opts, "ro", sizeof(opts));
- else
- strlcat(opts, "rw", sizeof(opts));
- if (flags & MNT_SYNCHRONOUS)
- strlcat(opts, ",sync", sizeof(opts));
- if (flags & MNT_NOEXEC)
- strlcat(opts, ",noexec", sizeof(opts));
- if (flags & MNT_NOSUID)
- strlcat(opts, ",nosuid", sizeof(opts));
- if (flags & MNT_UNION)
- strlcat(opts, ",union", sizeof(opts));
- if (flags & MNT_ASYNC)
- strlcat(opts, ",async", sizeof(opts));
- if (flags & MNT_SUIDDIR)
- strlcat(opts, ",suiddir", sizeof(opts));
- if (flags & MNT_SOFTDEP)
- strlcat(opts, ",softdep", sizeof(opts));
- if (flags & MNT_NOSYMFOLLOW)
- strlcat(opts, ",nosymfollow", sizeof(opts));
- if (flags & MNT_GJOURNAL)
- strlcat(opts, ",gjournal", sizeof(opts));
- if (flags & MNT_MULTILABEL)
- strlcat(opts, ",multilabel", sizeof(opts));
- if (flags & MNT_ACLS)
- strlcat(opts, ",acls", sizeof(opts));
- if (flags & MNT_NOATIME)
- strlcat(opts, ",noatime", sizeof(opts));
- if (flags & MNT_NOCLUSTERR)
- strlcat(opts, ",noclusterr", sizeof(opts));
- if (flags & MNT_NOCLUSTERW)
- strlcat(opts, ",noclusterw", sizeof(opts));
- if (flags & MNT_NFS4ACLS)
- strlcat(opts, ",nfs4acls", sizeof(opts));
-
- py_tuple = Py_BuildValue("(ssss)",
- fs[i].f_mntfromname, // device
- fs[i].f_mntonname, // mount point
- fs[i].f_fstypename, // fs type
- opts); // options
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
-
- free(fs);
- return py_retlist;
-
-error:
- Py_XDECREF(py_tuple);
- Py_DECREF(py_retlist);
- if (fs != NULL)
- free(fs);
- return NULL;
-}
-
-
-/*
- * Return a Python list of named tuples with overall network I/O information
- */
-static PyObject *
-psutil_net_io_counters(PyObject *self, PyObject *args)
-{
- char *buf = NULL, *lim, *next;
- struct if_msghdr *ifm;
- int mib[6];
- size_t len;
- PyObject *py_retdict = PyDict_New();
- PyObject *py_ifc_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- mib[0] = CTL_NET; // networking subsystem
- mib[1] = PF_ROUTE; // type of information
- mib[2] = 0; // protocol (IPPROTO_xxx)
- mib[3] = 0; // address family
- mib[4] = NET_RT_IFLIST; // operation
- mib[5] = 0;
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- buf = malloc(len);
- if (buf == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- lim = buf + len;
-
- for (next = buf; next < lim; ) {
- py_ifc_info = NULL;
- ifm = (struct if_msghdr *)next;
- next += ifm->ifm_msglen;
-
- if (ifm->ifm_type == RTM_IFINFO) {
- struct if_msghdr *if2m = (struct if_msghdr *)ifm;
- struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
- char ifc_name[32];
-
- strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
- ifc_name[sdl->sdl_nlen] = 0;
- // XXX: ignore usbus interfaces:
- // http://lists.freebsd.org/pipermail/freebsd-current/
- // 2011-October/028752.html
- // 'ifconfig -a' doesn't show them, nor do we.
- if (strncmp(ifc_name, "usbus", 5) == 0)
- continue;
-
- py_ifc_info = Py_BuildValue("(kkkkkkki)",
- if2m->ifm_data.ifi_obytes,
- if2m->ifm_data.ifi_ibytes,
- if2m->ifm_data.ifi_opackets,
- if2m->ifm_data.ifi_ipackets,
- if2m->ifm_data.ifi_ierrors,
- if2m->ifm_data.ifi_oerrors,
- if2m->ifm_data.ifi_iqdrops,
- 0); // dropout not supported
- if (!py_ifc_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info))
- goto error;
- Py_DECREF(py_ifc_info);
- }
- else {
- continue;
- }
- }
-
- free(buf);
- return py_retdict;
-
-error:
- Py_XDECREF(py_ifc_info);
- Py_DECREF(py_retdict);
- if (buf != NULL)
- free(buf);
- return NULL;
-}
-
-
-/*
- * Return a Python dict of tuples for disk I/O information
- */
-static PyObject *
-psutil_disk_io_counters(PyObject *self, PyObject *args)
-{
- int i;
- struct statinfo stats;
-
- PyObject *py_retdict = PyDict_New();
- PyObject *py_disk_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- if (devstat_checkversion(NULL) < 0) {
- PyErr_Format(PyExc_RuntimeError, "devstat_checkversion() failed");
- goto error;
- }
-
- stats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo));
- if (stats.dinfo == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- bzero(stats.dinfo, sizeof(struct devinfo));
-
- if (devstat_getdevs(NULL, &stats) == -1) {
- PyErr_Format(PyExc_RuntimeError, "devstat_getdevs() failed");
- goto error;
- }
-
- for (i = 0; i < stats.dinfo->numdevs; i++) {
- py_disk_info = NULL;
- struct devstat current;
- char disk_name[128];
- current = stats.dinfo->devices[i];
- snprintf(disk_name, sizeof(disk_name), "%s%d",
- current.device_name,
- current.unit_number);
-
- py_disk_info = Py_BuildValue(
- "(KKKKLL)",
- current.operations[DEVSTAT_READ], // no reads
- current.operations[DEVSTAT_WRITE], // no writes
- current.bytes[DEVSTAT_READ], // bytes read
- current.bytes[DEVSTAT_WRITE], // bytes written
- (long long)devstat_compute_etime(
- &current.duration[DEVSTAT_READ], NULL), // r time
- (long long)devstat_compute_etime(
- &current.duration[DEVSTAT_WRITE], NULL)); // w time
- if (!py_disk_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
- goto error;
- Py_DECREF(py_disk_info);
- }
-
- if (stats.dinfo->mem_ptr)
- free(stats.dinfo->mem_ptr);
- free(stats.dinfo);
- return py_retdict;
-
-error:
- Py_XDECREF(py_disk_info);
- Py_DECREF(py_retdict);
- if (stats.dinfo != NULL)
- free(stats.dinfo);
- return NULL;
-}
-
-
-/*
- * Return currently connected users as a list of tuples.
- */
-static PyObject *
-psutil_users(PyObject *self, PyObject *args)
-{
- PyObject *ret_list = PyList_New(0);
- PyObject *tuple = NULL;
-
- if (ret_list == NULL)
- return NULL;
-
-#if __FreeBSD_version < 900000
- struct utmp ut;
- FILE *fp;
-
- fp = fopen(_PATH_UTMP, "r");
- if (fp == NULL) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- while (fread(&ut, sizeof(ut), 1, fp) == 1) {
- if (*ut.ut_name == '\0')
- continue;
- tuple = Py_BuildValue(
- "(sssf)",
- ut.ut_name, // username
- ut.ut_line, // tty
- ut.ut_host, // hostname
- (float)ut.ut_time); // start time
- if (!tuple) {
- fclose(fp);
- goto error;
- }
- if (PyList_Append(ret_list, tuple)) {
- fclose(fp);
- goto error;
- }
- Py_DECREF(tuple);
- }
-
- fclose(fp);
-#else
- struct utmpx *utx;
-
- while ((utx = getutxent()) != NULL) {
- if (utx->ut_type != USER_PROCESS)
- continue;
- tuple = Py_BuildValue(
- "(sssf)",
- utx->ut_user, // username
- utx->ut_line, // tty
- utx->ut_host, // hostname
- (float)utx->ut_tv.tv_sec // start time
- );
-
- if (!tuple) {
- endutxent();
- goto error;
- }
- if (PyList_Append(ret_list, tuple)) {
- endutxent();
- goto error;
- }
- Py_DECREF(tuple);
- }
-
- endutxent();
-#endif
- return ret_list;
-
-error:
- Py_XDECREF(tuple);
- Py_DECREF(ret_list);
- return NULL;
-}
-
-
-
-/*
- * System-wide open connections.
- */
-
-#define HASHSIZE 1009
-static struct xfile *psutil_xfiles;
-static int psutil_nxfiles;
-
-int
-psutil_populate_xfiles()
-{
- size_t len;
-
- if ((psutil_xfiles = malloc(len = sizeof *psutil_xfiles)) == NULL) {
- PyErr_NoMemory();
- return 0;
- }
- while (sysctlbyname("kern.file", psutil_xfiles, &len, 0, 0) == -1) {
- if (errno != ENOMEM) {
- PyErr_SetFromErrno(0);
- return 0;
- }
- len *= 2;
- if ((psutil_xfiles = realloc(psutil_xfiles, len)) == NULL) {
- PyErr_NoMemory();
- return 0;
- }
- }
- if (len > 0 && psutil_xfiles->xf_size != sizeof *psutil_xfiles) {
- PyErr_Format(PyExc_RuntimeError, "struct xfile size mismatch");
- return 0;
- }
- psutil_nxfiles = len / sizeof *psutil_xfiles;
- return 1;
-}
-
-int
-psutil_get_pid_from_sock(int sock_hash)
-{
- struct xfile *xf;
- int hash, n;
- for (xf = psutil_xfiles, n = 0; n < psutil_nxfiles; ++n, ++xf) {
- if (xf->xf_data == NULL)
- continue;
- hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
- if (sock_hash == hash)
- return xf->xf_pid;
- }
- return -1;
-}
-
-
-// Reference:
-// https://gitorious.org/freebsd/freebsd/source/
-// f1d6f4778d2044502209708bc167c05f9aa48615:usr.bin/sockstat/sockstat.c
-int psutil_gather_inet(int proto, PyObject *py_retlist)
-{
- struct xinpgen *xig, *exig;
- struct xinpcb *xip;
- struct xtcpcb *xtp;
- struct inpcb *inp;
- struct xsocket *so;
- const char *varname = NULL;
- size_t len, bufsize;
- void *buf;
- int hash;
- int retry;
- int type;
-
- PyObject *tuple = NULL;
- PyObject *laddr = NULL;
- PyObject *raddr = NULL;
-
- switch (proto) {
- case IPPROTO_TCP:
- varname = "net.inet.tcp.pcblist";
- type = SOCK_STREAM;
- break;
- case IPPROTO_UDP:
- varname = "net.inet.udp.pcblist";
- type = SOCK_DGRAM;
- break;
- }
-
- buf = NULL;
- bufsize = 8192;
- retry = 5;
- do {
- for (;;) {
- buf = realloc(buf, bufsize);
- if (buf == NULL)
- continue; // XXX
- len = bufsize;
- if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
- break;
- if (errno != ENOMEM) {
- PyErr_SetFromErrno(0);
- goto error;
- }
- bufsize *= 2;
- }
- xig = (struct xinpgen *)buf;
- exig = (struct xinpgen *)(void *)((char *)buf + len - sizeof *exig);
- if (xig->xig_len != sizeof *xig || exig->xig_len != sizeof *exig) {
- PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
- goto error;
- }
- } while (xig->xig_gen != exig->xig_gen && retry--);
-
-
- for (;;) {
- int lport, rport, pid, status, family;
-
- xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
- if (xig >= exig)
- break;
-
- switch (proto) {
- case IPPROTO_TCP:
- xtp = (struct xtcpcb *)xig;
- if (xtp->xt_len != sizeof *xtp) {
- PyErr_Format(PyExc_RuntimeError,
- "struct xtcpcb size mismatch");
- goto error;
- }
- inp = &xtp->xt_inp;
- so = &xtp->xt_socket;
- status = xtp->xt_tp.t_state;
- break;
- case IPPROTO_UDP:
- xip = (struct xinpcb *)xig;
- if (xip->xi_len != sizeof *xip) {
- PyErr_Format(PyExc_RuntimeError,
- "struct xinpcb size mismatch");
- goto error;
- }
- inp = &xip->xi_inp;
- so = &xip->xi_socket;
- status = PSUTIL_CONN_NONE;
- break;
- default:
- PyErr_Format(PyExc_RuntimeError, "invalid proto");
- goto error;
- }
-
- char lip[200], rip[200];
-
- hash = (int)((uintptr_t)so->xso_so % HASHSIZE);
- pid = psutil_get_pid_from_sock(hash);
- if (pid < 0)
- continue;
- lport = ntohs(inp->inp_lport);
- rport = ntohs(inp->inp_fport);
-
- if (inp->inp_vflag & INP_IPV4) {
- family = AF_INET;
- inet_ntop(AF_INET, &inp->inp_laddr.s_addr, lip, sizeof(lip));
- inet_ntop(AF_INET, &inp->inp_faddr.s_addr, rip, sizeof(rip));
- }
- else if (inp->inp_vflag & INP_IPV6) {
- family = AF_INET6;
- inet_ntop(AF_INET6, &inp->in6p_laddr.s6_addr, lip, sizeof(lip));
- inet_ntop(AF_INET6, &inp->in6p_faddr.s6_addr, rip, sizeof(rip));
- }
-
- // construct python tuple/list
- laddr = Py_BuildValue("(si)", lip, lport);
- if (!laddr)
- goto error;
- if (rport != 0)
- raddr = Py_BuildValue("(si)", rip, rport);
- else
- raddr = Py_BuildValue("()");
- if (!raddr)
- goto error;
- tuple = Py_BuildValue("(iiiNNii)", -1, family, type, laddr, raddr,
- status, pid);
- if (!tuple)
- goto error;
- if (PyList_Append(py_retlist, tuple))
- goto error;
- Py_DECREF(tuple);
- }
-
- free(buf);
- return 1;
-
-error:
- Py_XDECREF(tuple);
- Py_XDECREF(laddr);
- Py_XDECREF(raddr);
- free(buf);
- return 0;
-}
-
-
-int psutil_gather_unix(int proto, PyObject *py_retlist)
-{
- struct xunpgen *xug, *exug;
- struct xunpcb *xup;
- const char *varname = NULL;
- const char *protoname = NULL;
- size_t len;
- size_t bufsize;
- void *buf;
- int hash;
- int retry;
- int pid;
- struct sockaddr_un *sun;
- char path[PATH_MAX];
-
- PyObject *tuple = NULL;
- PyObject *laddr = NULL;
- PyObject *raddr = NULL;
-
- switch (proto) {
- case SOCK_STREAM:
- varname = "net.local.stream.pcblist";
- protoname = "stream";
- break;
- case SOCK_DGRAM:
- varname = "net.local.dgram.pcblist";
- protoname = "dgram";
- break;
- }
-
- buf = NULL;
- bufsize = 8192;
- retry = 5;
-
- do {
- for (;;) {
- buf = realloc(buf, bufsize);
- if (buf == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- len = bufsize;
- if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
- break;
- if (errno != ENOMEM) {
- PyErr_SetFromErrno(0);
- goto error;
- }
- bufsize *= 2;
- }
- xug = (struct xunpgen *)buf;
- exug = (struct xunpgen *)(void *)
- ((char *)buf + len - sizeof *exug);
- if (xug->xug_len != sizeof *xug || exug->xug_len != sizeof *exug) {
- PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
- goto error;
- }
- } while (xug->xug_gen != exug->xug_gen && retry--);
-
- for (;;) {
- xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
- if (xug >= exug)
- break;
- xup = (struct xunpcb *)xug;
- if (xup->xu_len != sizeof *xup)
- goto error;
-
- hash = (int)((uintptr_t) xup->xu_socket.xso_so % HASHSIZE);
- pid = psutil_get_pid_from_sock(hash);
- if (pid < 0)
- continue;
-
- sun = (struct sockaddr_un *)&xup->xu_addr;
- snprintf(path, sizeof(path), "%.*s",
- (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
- sun->sun_path);
-
- tuple = Py_BuildValue("(iiisOii)", -1, AF_UNIX, proto, path, Py_None,
- PSUTIL_CONN_NONE, pid);
- if (!tuple)
- goto error;
- if (PyList_Append(py_retlist, tuple))
- goto error;
- Py_DECREF(tuple);
- Py_INCREF(Py_None);
- }
-
- free(buf);
- return 1;
-
-error:
- Py_XDECREF(tuple);
- Py_XDECREF(laddr);
- Py_XDECREF(raddr);
- free(buf);
- return 0;
-}
-
-
-/*
- * Return system-wide open connections.
- */
-static PyObject*
-psutil_net_connections(PyObject* self, PyObject* args)
-{
- PyObject *py_retlist = PyList_New(0);
-
- if (py_retlist == NULL)
- return NULL;
- if (psutil_populate_xfiles() != 1)
- goto error;
- if (psutil_gather_inet(IPPROTO_TCP, py_retlist) == 0)
- goto error;
- if (psutil_gather_inet(IPPROTO_UDP, py_retlist) == 0)
- goto error;
- if (psutil_gather_unix(SOCK_STREAM, py_retlist) == 0)
- goto error;
- if (psutil_gather_unix(SOCK_DGRAM, py_retlist) == 0)
- goto error;
-
- free(psutil_xfiles);
- return py_retlist;
-
-error:
- Py_DECREF(py_retlist);
- free(psutil_xfiles);
- return NULL;
-}
-
-
-/*
- * Get process CPU affinity.
- * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c
- */
-static PyObject*
-psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args)
-{
- long pid;
- int ret;
- int i;
- cpuset_t mask;
- PyObject* py_retlist;
- PyObject* py_cpu_num;
-
- if (!PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
- sizeof(mask), &mask);
- if (ret != 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
-
- py_retlist = PyList_New(0);
- if (py_retlist == NULL)
- return NULL;
-
- for (i = 0; i < CPU_SETSIZE; i++) {
- if (CPU_ISSET(i, &mask)) {
- py_cpu_num = Py_BuildValue("i", i);
- if (py_cpu_num == NULL)
- goto error;
- if (PyList_Append(py_retlist, py_cpu_num))
- goto error;
- }
- }
-
- return py_retlist;
-
-error:
- Py_XDECREF(py_cpu_num);
- Py_DECREF(py_retlist);
- return NULL;
-}
-
-
-/*
- * Set process CPU affinity.
- * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c
- */
-static PyObject *
-psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
-{
- long pid;
- int i;
- int seq_len;
- int ret;
- cpuset_t cpu_set;
- PyObject *py_cpu_set;
- PyObject *py_cpu_seq = NULL;
-
- if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
- return NULL;
-
- py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer");
- if (!py_cpu_seq)
- return NULL;
- seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);
-
- // calculate the mask
- CPU_ZERO(&cpu_set);
- for (i = 0; i < seq_len; i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i);
-#if PY_MAJOR_VERSION >= 3
- long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
- if (value == -1 && PyErr_Occurred())
- goto error;
- CPU_SET(value, &cpu_set);
- }
-
- // set affinity
- ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
- sizeof(cpu_set), &cpu_set);
- if (ret != 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- Py_DECREF(py_cpu_seq);
- Py_RETURN_NONE;
-
-error:
- if (py_cpu_seq != NULL)
- Py_DECREF(py_cpu_seq);
- return NULL;
-}
-
-
-/*
- * define the psutil C module methods and initialize the module.
- */
-static PyMethodDef
-PsutilMethods[] =
-{
- // --- per-process functions
-
- {"proc_name", psutil_proc_name, METH_VARARGS,
- "Return process name"},
- {"proc_connections", psutil_proc_connections, METH_VARARGS,
- "Return connections opened by process"},
- {"proc_exe", psutil_proc_exe, METH_VARARGS,
- "Return process pathname executable"},
- {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
- "Return process cmdline as a list of cmdline arguments"},
- {"proc_ppid", psutil_proc_ppid, METH_VARARGS,
- "Return process ppid as an integer"},
- {"proc_uids", psutil_proc_uids, METH_VARARGS,
- "Return process real effective and saved user ids as a Python tuple"},
- {"proc_gids", psutil_proc_gids, METH_VARARGS,
- "Return process real effective and saved group ids as a Python tuple"},
- {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
- "Return tuple of user/kern time for the given PID"},
- {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
- "Return a float indicating the process create time expressed in "
- "seconds since the epoch"},
- {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
- "Return extended memory info for a process as a Python tuple."},
- {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS,
- "Return number of threads used by process"},
- {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
- "Return the number of context switches performed by process"},
- {"proc_threads", psutil_proc_threads, METH_VARARGS,
- "Return process threads"},
- {"proc_status", psutil_proc_status, METH_VARARGS,
- "Return process status as an integer"},
- {"proc_io_counters", psutil_proc_io_counters, METH_VARARGS,
- "Return process IO counters"},
- {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS,
- "Return process tty (terminal) number"},
- {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
- "Return process CPU affinity."},
- {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
- "Set process CPU affinity."},
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
- {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
- "Return files opened by process as a list of (path, fd) tuples"},
- {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
- "Return process current working directory."},
- {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
- "Return a list of tuples for every process's memory map"},
- {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS,
- "Return the number of file descriptors opened by this process"},
-#endif
-
- // --- system-related functions
-
- {"pids", psutil_pids, METH_VARARGS,
- "Returns a list of PIDs currently running on the system"},
- {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
- "Return number of logical CPUs on the system"},
- {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
- "Return an XML string to determine the number physical CPUs."},
- {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
- "Return system virtual memory usage statistics"},
- {"swap_mem", psutil_swap_mem, METH_VARARGS,
- "Return swap mem stats"},
- {"cpu_times", psutil_cpu_times, METH_VARARGS,
- "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
- {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
- "Return system per-cpu times as a list of tuples"},
-#endif
- {"boot_time", psutil_boot_time, METH_VARARGS,
- "Return the system boot time expressed in seconds since the epoch."},
- {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
- "Return a list of tuples including device, mount point and "
- "fs type for all partitions mounted on the system."},
- {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
- "Return dict of tuples of networks I/O information."},
- {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
- "Return a Python dict of tuples for disk I/O information"},
- {"users", psutil_users, METH_VARARGS,
- "Return currently connected users as a list of tuples"},
- {"net_connections", psutil_net_connections, METH_VARARGS,
- "Return system-wide open connections."},
-
- {NULL, NULL, 0, NULL}
-};
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int
-psutil_bsd_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int
-psutil_bsd_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-static struct PyModuleDef
- moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_bsd",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_bsd_traverse,
- psutil_bsd_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_bsd(void)
-
-#else
-#define INITERROR return
-
-void init_psutil_bsd(void)
-#endif
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods);
-#endif
- PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
-
- // process status constants
- PyModule_AddIntConstant(module, "SSTOP", SSTOP);
- PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
- PyModule_AddIntConstant(module, "SRUN", SRUN);
- PyModule_AddIntConstant(module, "SIDL", SIDL);
- PyModule_AddIntConstant(module, "SWAIT", SWAIT);
- PyModule_AddIntConstant(module, "SLOCK", SLOCK);
- PyModule_AddIntConstant(module, "SZOMB", SZOMB);
- // connection status constants
- PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
- PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
- PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
- PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
- PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
- PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
- PyModule_AddIntConstant(module, "TCPS_SYN_RECEIVED", TCPS_SYN_RECEIVED);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
- PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
- PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
- PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
-
- if (module == NULL)
- INITERROR;
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_bsd.h b/python/psutil/psutil/_psutil_bsd.h
deleted file mode 100644
index 803957dac..000000000
--- a/python/psutil/psutil/_psutil_bsd.h
+++ /dev/null
@@ -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
diff --git a/python/psutil/psutil/_psutil_common.c b/python/psutil/psutil/_psutil_common.c
deleted file mode 100644
index 1c530d4df..000000000
--- a/python/psutil/psutil/_psutil_common.c
+++ /dev/null
@@ -1,37 +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.
- *
- * Routines common to all platforms.
- */
-
-#include <Python.h>
-
-
-/*
- * Set OSError(errno=ESRCH, strerror="No such process") Python exception.
- */
-PyObject *
-NoSuchProcess(void) {
- PyObject *exc;
- char *msg = strerror(ESRCH);
- exc = PyObject_CallFunction(PyExc_OSError, "(is)", ESRCH, msg);
- PyErr_SetObject(PyExc_OSError, exc);
- Py_XDECREF(exc);
- return NULL;
-}
-
-
-/*
- * Set OSError(errno=EACCES, strerror="Permission denied") Python exception.
- */
-PyObject *
-AccessDenied(void) {
- PyObject *exc;
- char *msg = strerror(EACCES);
- exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg);
- PyErr_SetObject(PyExc_OSError, exc);
- Py_XDECREF(exc);
- return NULL;
-}
diff --git a/python/psutil/psutil/_psutil_common.h b/python/psutil/psutil/_psutil_common.h
deleted file mode 100644
index 43021a72d..000000000
--- a/python/psutil/psutil/_psutil_common.h
+++ /dev/null
@@ -1,10 +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>
-
-PyObject* AccessDenied(void);
-PyObject* NoSuchProcess(void);
diff --git a/python/psutil/psutil/_psutil_linux.c b/python/psutil/psutil/_psutil_linux.c
deleted file mode 100644
index a3bf5643c..000000000
--- a/python/psutil/psutil/_psutil_linux.c
+++ /dev/null
@@ -1,689 +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.
- *
- * Linux-specific functions.
- */
-
-#ifndef _GNU_SOURCE
- #define _GNU_SOURCE 1
-#endif
-#include <Python.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <mntent.h>
-#include <features.h>
-#include <utmp.h>
-#include <sched.h>
-#include <linux/version.h>
-#include <sys/syscall.h>
-#include <sys/sysinfo.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <linux/sockios.h>
-#include <linux/if.h>
-#include <linux/ethtool.h>
-
-#include "_psutil_linux.h"
-
-/* The minimum number of CPUs allocated in a cpu_set_t */
-static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
-
-// Linux >= 2.6.13
-#define PSUTIL_HAVE_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
-
-// Linux >= 2.6.36 (supposedly) and glibc >= 13
-#define PSUTIL_HAVE_PRLIMIT \
- (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && \
- (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 13) && \
- defined(__NR_prlimit64)
-
-#if PSUTIL_HAVE_PRLIMIT
- #define _FILE_OFFSET_BITS 64
- #include <time.h>
- #include <sys/resource.h>
-#endif
-
-
-#if PSUTIL_HAVE_IOPRIO
-enum {
- IOPRIO_WHO_PROCESS = 1,
-};
-
-// May happen on old RedHat versions, see:
-// https://github.com/giampaolo/psutil/issues/607
-#ifndef DUPLEX_UNKNOWN
- #define DUPLEX_UNKNOWN 0xff
-#endif
-
-static inline int
-ioprio_get(int which, int who)
-{
- return syscall(__NR_ioprio_get, which, who);
-}
-
-static inline int
-ioprio_set(int which, int who, int ioprio)
-{
- return syscall(__NR_ioprio_set, which, who, ioprio);
-}
-
-#define IOPRIO_CLASS_SHIFT 13
-#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
-
-#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
-#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
-#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
-
-
-/*
- * Return a (ioclass, iodata) Python tuple representing process I/O priority.
- */
-static PyObject *
-psutil_proc_ioprio_get(PyObject *self, PyObject *args)
-{
- long pid;
- int ioprio, ioclass, iodata;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
- if (ioprio == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
- ioclass = IOPRIO_PRIO_CLASS(ioprio);
- iodata = IOPRIO_PRIO_DATA(ioprio);
- return Py_BuildValue("ii", ioclass, iodata);
-}
-
-
-/*
- * A wrapper around ioprio_set(); sets process I/O priority.
- * ioclass can be either IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE
- * or 0. iodata goes from 0 to 7 depending on ioclass specified.
- */
-static PyObject *
-psutil_proc_ioprio_set(PyObject *self, PyObject *args)
-{
- long pid;
- int ioprio, ioclass, iodata;
- int retval;
-
- if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata))
- return NULL;
- ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata);
- retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio);
- if (retval == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
- Py_RETURN_NONE;
-}
-#endif
-
-
-#if PSUTIL_HAVE_PRLIMIT
-/*
- * A wrapper around prlimit(2); sets process resource limits.
- * This can be used for both get and set, in which case extra
- * 'soft' and 'hard' args must be provided.
- */
-static PyObject *
-psutil_linux_prlimit(PyObject *self, PyObject *args)
-{
- long pid;
- int ret, resource;
- struct rlimit old, new;
- struct rlimit *newp = NULL;
- PyObject *soft = NULL;
- PyObject *hard = NULL;
-
- if (! PyArg_ParseTuple(args, "li|OO", &pid, &resource, &soft, &hard))
- return NULL;
-
- // get
- if (soft == NULL && hard == NULL) {
- ret = prlimit(pid, resource, NULL, &old);
- if (ret == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
-#if defined(PSUTIL_HAVE_LONG_LONG)
- if (sizeof(old.rlim_cur) > sizeof(long)) {
- return Py_BuildValue("LL",
- (PY_LONG_LONG)old.rlim_cur,
- (PY_LONG_LONG)old.rlim_max);
- }
-#endif
- return Py_BuildValue("ll", (long)old.rlim_cur, (long)old.rlim_max);
- }
-
- // set
- else {
-#if defined(PSUTIL_HAVE_LARGEFILE_SUPPORT)
- new.rlim_cur = PyLong_AsLongLong(soft);
- if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
- return NULL;
- new.rlim_max = PyLong_AsLongLong(hard);
- if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
- return NULL;
-#else
- new.rlim_cur = PyLong_AsLong(soft);
- if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
- return NULL;
- new.rlim_max = PyLong_AsLong(hard);
- if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
- return NULL;
-#endif
- newp = &new;
- ret = prlimit(pid, resource, newp, &old);
- if (ret == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
- Py_RETURN_NONE;
- }
-}
-#endif
-
-
-/*
- * Return disk mounted partitions as a list of tuples including device,
- * mount point and filesystem type
- */
-static PyObject *
-psutil_disk_partitions(PyObject *self, PyObject *args)
-{
- FILE *file = NULL;
- struct mntent *entry;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- // MOUNTED constant comes from mntent.h and it's == '/etc/mtab'
- Py_BEGIN_ALLOW_THREADS
- file = setmntent(MOUNTED, "r");
- Py_END_ALLOW_THREADS
- if ((file == 0) || (file == NULL)) {
- PyErr_SetFromErrnoWithFilename(PyExc_OSError, MOUNTED);
- goto error;
- }
-
- while ((entry = getmntent(file))) {
- if (entry == NULL) {
- PyErr_Format(PyExc_RuntimeError, "getmntent() failed");
- goto error;
- }
- py_tuple = Py_BuildValue("(ssss)",
- entry->mnt_fsname, // device
- entry->mnt_dir, // mount point
- entry->mnt_type, // fs type
- entry->mnt_opts); // options
- if (! py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- endmntent(file);
- return py_retlist;
-
-error:
- if (file != NULL)
- endmntent(file);
- Py_XDECREF(py_tuple);
- Py_DECREF(py_retlist);
- return NULL;
-}
-
-
-/*
- * A wrapper around sysinfo(), return system memory usage statistics.
- */
-static PyObject *
-psutil_linux_sysinfo(PyObject *self, PyObject *args)
-{
- struct sysinfo info;
-
- if (sysinfo(&info) != 0)
- return PyErr_SetFromErrno(PyExc_OSError);
- // note: boot time might also be determined from here
- return Py_BuildValue(
- "(KKKKKK)",
- (unsigned long long)info.totalram * info.mem_unit, // total
- (unsigned long long)info.freeram * info.mem_unit, // free
- (unsigned long long)info.bufferram * info.mem_unit, // buffer
- (unsigned long long)info.sharedram * info.mem_unit, // shared
- (unsigned long long)info.totalswap * info.mem_unit, // swap tot
- (unsigned long long)info.freeswap * info.mem_unit); // swap free
-}
-
-
-/*
- * Return process CPU affinity as a Python list
- * The dual implementation exists because of:
- * https://github.com/giampaolo/psutil/issues/536
- */
-
-#ifdef CPU_ALLOC
-
-static PyObject *
-psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
-{
- int cpu, ncpus, count, cpucount_s;
- long pid;
- size_t setsize;
- cpu_set_t *mask = NULL;
- PyObject *res = NULL;
-
- if (!PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- ncpus = NCPUS_START;
- while (1) {
- setsize = CPU_ALLOC_SIZE(ncpus);
- mask = CPU_ALLOC(ncpus);
- if (mask == NULL)
- return PyErr_NoMemory();
- if (sched_getaffinity(pid, setsize, mask) == 0)
- break;
- CPU_FREE(mask);
- if (errno != EINVAL)
- return PyErr_SetFromErrno(PyExc_OSError);
- if (ncpus > INT_MAX / 2) {
- PyErr_SetString(PyExc_OverflowError, "could not allocate "
- "a large enough CPU set");
- return NULL;
- }
- ncpus = ncpus * 2;
- }
-
- res = PyList_New(0);
- if (res == NULL)
- goto error;
-
- cpucount_s = CPU_COUNT_S(setsize, mask);
- for (cpu = 0, count = cpucount_s; count; cpu++) {
- if (CPU_ISSET_S(cpu, setsize, mask)) {
-#if PY_MAJOR_VERSION >= 3
- PyObject *cpu_num = PyLong_FromLong(cpu);
-#else
- PyObject *cpu_num = PyInt_FromLong(cpu);
-#endif
- if (cpu_num == NULL)
- goto error;
- if (PyList_Append(res, cpu_num)) {
- Py_DECREF(cpu_num);
- goto error;
- }
- Py_DECREF(cpu_num);
- --count;
- }
- }
- CPU_FREE(mask);
- return res;
-
-error:
- if (mask)
- CPU_FREE(mask);
- Py_XDECREF(res);
- return NULL;
-}
-#else
-
-
-/*
- * Alternative implementation in case CPU_ALLOC is not defined.
- */
-static PyObject *
-psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
-{
- cpu_set_t cpuset;
- unsigned int len = sizeof(cpu_set_t);
- long pid;
- int i;
- PyObject* py_retlist = NULL;
- PyObject *py_cpu_num = NULL;
-
- if (!PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- CPU_ZERO(&cpuset);
- if (sched_getaffinity(pid, len, &cpuset) < 0)
- return PyErr_SetFromErrno(PyExc_OSError);
-
- py_retlist = PyList_New(0);
- if (py_retlist == NULL)
- goto error;
- for (i = 0; i < CPU_SETSIZE; ++i) {
- if (CPU_ISSET(i, &cpuset)) {
- py_cpu_num = Py_BuildValue("i", i);
- if (py_cpu_num == NULL)
- goto error;
- if (PyList_Append(py_retlist, py_cpu_num))
- goto error;
- Py_DECREF(py_cpu_num);
- }
- }
-
- return py_retlist;
-
-error:
- Py_XDECREF(py_cpu_num);
- Py_DECREF(py_retlist);
- return NULL;
-}
-#endif
-
-/*
- * Set process CPU affinity; expects a bitmask
- */
-static PyObject *
-psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
-{
- cpu_set_t cpu_set;
- size_t len;
- long pid;
- int i, seq_len;
- PyObject *py_cpu_set;
- PyObject *py_cpu_seq = NULL;
-
- if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
- return NULL;
-
- if (!PySequence_Check(py_cpu_set)) {
- PyErr_Format(PyExc_TypeError, "sequence argument expected, got %s",
- Py_TYPE(py_cpu_set)->tp_name);
- goto error;
- }
-
- py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer");
- if (!py_cpu_seq)
- goto error;
- seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);
- CPU_ZERO(&cpu_set);
- for (i = 0; i < seq_len; i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i);
-#if PY_MAJOR_VERSION >= 3
- long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
- if (value == -1 && PyErr_Occurred())
- goto error;
- CPU_SET(value, &cpu_set);
- }
-
- len = sizeof(cpu_set);
- if (sched_setaffinity(pid, len, &cpu_set)) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- Py_DECREF(py_cpu_seq);
- Py_RETURN_NONE;
-
-error:
- if (py_cpu_seq != NULL)
- Py_DECREF(py_cpu_seq);
- return NULL;
-}
-
-
-/*
- * Return currently connected users as a list of tuples.
- */
-static PyObject *
-psutil_users(PyObject *self, PyObject *args)
-{
- PyObject *ret_list = PyList_New(0);
- PyObject *tuple = NULL;
- PyObject *user_proc = NULL;
- struct utmp *ut;
-
- if (ret_list == NULL)
- return NULL;
- setutent();
- while (NULL != (ut = getutent())) {
- tuple = NULL;
- user_proc = NULL;
- if (ut->ut_type == USER_PROCESS)
- user_proc = Py_True;
- else
- user_proc = Py_False;
- tuple = Py_BuildValue(
- "(sssfO)",
- ut->ut_user, // username
- ut->ut_line, // tty
- ut->ut_host, // hostname
- (float)ut->ut_tv.tv_sec, // tstamp
- user_proc // (bool) user process
- );
- if (! tuple)
- goto error;
- if (PyList_Append(ret_list, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- endutent();
- return ret_list;
-
-error:
- Py_XDECREF(tuple);
- Py_XDECREF(user_proc);
- Py_DECREF(ret_list);
- endutent();
- return NULL;
-}
-
-
-/*
- * Return stats about a particular network
- * interface. References:
- * https://github.com/dpaleino/wicd/blob/master/wicd/backends/be-ioctl.py
- * http://www.i-scream.org/libstatgrab/
- */
-static PyObject*
-psutil_net_if_stats(PyObject* self, PyObject* args)
-{
- char *nic_name;
- int sock = 0;
- int ret;
- int duplex;
- int speed;
- int mtu;
- struct ifreq ifr;
- struct ethtool_cmd ethcmd;
- PyObject *py_is_up = NULL;
- PyObject *py_ret = NULL;
-
- if (! PyArg_ParseTuple(args, "s", &nic_name))
- return NULL;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock == -1)
- goto error;
- strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
-
- // is up?
- ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
- if (ret == -1)
- goto error;
- if ((ifr.ifr_flags & IFF_UP) != 0)
- py_is_up = Py_True;
- else
- py_is_up = Py_False;
- Py_INCREF(py_is_up);
-
- // MTU
- ret = ioctl(sock, SIOCGIFMTU, &ifr);
- if (ret == -1)
- goto error;
- mtu = ifr.ifr_mtu;
-
- // duplex and speed
- memset(&ethcmd, 0, sizeof ethcmd);
- ethcmd.cmd = ETHTOOL_GSET;
- ifr.ifr_data = (caddr_t)&ethcmd;
- ret = ioctl(sock, SIOCETHTOOL, &ifr);
-
- if (ret != -1) {
- duplex = ethcmd.duplex;
- speed = ethcmd.speed;
- }
- else {
- if (errno == EOPNOTSUPP) {
- // we typically get here in case of wi-fi cards
- duplex = DUPLEX_UNKNOWN;
- speed = 0;
- }
- else {
- goto error;
- }
- }
-
- close(sock);
- py_ret = Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu);
- if (!py_ret)
- goto error;
- Py_DECREF(py_is_up);
- return py_ret;
-
-error:
- Py_XDECREF(py_is_up);
- if (sock != 0)
- close(sock);
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
-}
-
-
-/*
- * Define the psutil C module methods and initialize the module.
- */
-static PyMethodDef
-PsutilMethods[] =
-{
- // --- per-process functions
-
-#if PSUTIL_HAVE_IOPRIO
- {"proc_ioprio_get", psutil_proc_ioprio_get, METH_VARARGS,
- "Get process I/O priority"},
- {"proc_ioprio_set", psutil_proc_ioprio_set, METH_VARARGS,
- "Set process I/O priority"},
-#endif
- {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
- "Return process CPU affinity as a Python long (the bitmask)."},
- {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
- "Set process CPU affinity; expects a bitmask."},
-
- // --- system related functions
-
- {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
- "Return disk mounted partitions as a list of tuples including "
- "device, mount point and filesystem type"},
- {"users", psutil_users, METH_VARARGS,
- "Return currently connected users as a list of tuples"},
- {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
- "Return NIC stats (isup, duplex, speed, mtu)"},
-
- // --- linux specific
-
- {"linux_sysinfo", psutil_linux_sysinfo, METH_VARARGS,
- "A wrapper around sysinfo(), return system memory usage statistics"},
-#if PSUTIL_HAVE_PRLIMIT
- {"linux_prlimit", psutil_linux_prlimit, METH_VARARGS,
- "Get or set process resource limits."},
-#endif
-
-
- {NULL, NULL, 0, NULL}
-};
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int
-psutil_linux_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int
-psutil_linux_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-static struct PyModuleDef
- moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_linux",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_linux_traverse,
- psutil_linux_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_linux(void)
-
-#else
-#define INITERROR return
-
-void init_psutil_linux(void)
-#endif
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods);
-#endif
-
-
- PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
-#if PSUTIL_HAVE_PRLIMIT
- PyModule_AddIntConstant(module, "RLIM_INFINITY", RLIM_INFINITY);
- PyModule_AddIntConstant(module, "RLIMIT_AS", RLIMIT_AS);
- PyModule_AddIntConstant(module, "RLIMIT_CORE", RLIMIT_CORE);
- PyModule_AddIntConstant(module, "RLIMIT_CPU", RLIMIT_CPU);
- PyModule_AddIntConstant(module, "RLIMIT_DATA", RLIMIT_DATA);
- PyModule_AddIntConstant(module, "RLIMIT_FSIZE", RLIMIT_FSIZE);
- PyModule_AddIntConstant(module, "RLIMIT_LOCKS", RLIMIT_LOCKS);
- PyModule_AddIntConstant(module, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
- PyModule_AddIntConstant(module, "RLIMIT_NOFILE", RLIMIT_NOFILE);
- PyModule_AddIntConstant(module, "RLIMIT_NPROC", RLIMIT_NPROC);
- PyModule_AddIntConstant(module, "RLIMIT_RSS", RLIMIT_RSS);
- PyModule_AddIntConstant(module, "RLIMIT_STACK", RLIMIT_STACK);
-#ifdef RLIMIT_MSGQUEUE
- PyModule_AddIntConstant(module, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
-#endif
-#ifdef RLIMIT_NICE
- PyModule_AddIntConstant(module, "RLIMIT_NICE", RLIMIT_NICE);
-#endif
-#ifdef RLIMIT_RTPRIO
- PyModule_AddIntConstant(module, "RLIMIT_RTPRIO", RLIMIT_RTPRIO);
-#endif
-#ifdef RLIMIT_RTTIME
- PyModule_AddIntConstant(module, "RLIMIT_RTTIME", RLIMIT_RTTIME);
-#endif
-#ifdef RLIMIT_SIGPENDING
- PyModule_AddIntConstant(module, "RLIMIT_SIGPENDING", RLIMIT_SIGPENDING);
-#endif
-#endif
- PyModule_AddIntConstant(module, "DUPLEX_HALF", DUPLEX_HALF);
- PyModule_AddIntConstant(module, "DUPLEX_FULL", DUPLEX_FULL);
- PyModule_AddIntConstant(module, "DUPLEX_UNKNOWN", DUPLEX_UNKNOWN);
-
- if (module == NULL)
- INITERROR;
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_linux.h b/python/psutil/psutil/_psutil_linux.h
deleted file mode 100644
index ec6a33871..000000000
--- a/python/psutil/psutil/_psutil_linux.h
+++ /dev/null
@@ -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);
diff --git a/python/psutil/psutil/_psutil_osx.c b/python/psutil/psutil/_psutil_osx.c
deleted file mode 100644
index 3ebf8ff27..000000000
--- a/python/psutil/psutil/_psutil_osx.c
+++ /dev/null
@@ -1,1808 +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.
- *
- * OS X platform-specific module methods for _psutil_osx
- */
-
-#include <Python.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <utmpx.h>
-#include <sys/sysctl.h>
-#include <sys/vmmeter.h>
-#include <libproc.h>
-#include <sys/proc_info.h>
-#include <netinet/tcp_fsm.h>
-#include <arpa/inet.h>
-#include <net/if_dl.h>
-#include <pwd.h>
-
-#include <mach/mach.h>
-#include <mach/task.h>
-#include <mach/mach_init.h>
-#include <mach/host_info.h>
-#include <mach/mach_host.h>
-#include <mach/mach_traps.h>
-#include <mach/mach_vm.h>
-#include <mach/shared_region.h>
-
-#include <mach-o/loader.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/storage/IOBlockStorageDriver.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/IOBSD.h>
-
-#include "_psutil_osx.h"
-#include "_psutil_common.h"
-#include "arch/osx/process_info.h"
-
-
-/*
- * A wrapper around host_statistics() invoked with HOST_VM_INFO.
- */
-int
-psutil_sys_vminfo(vm_statistics_data_t *vmstat)
-{
- kern_return_t ret;
- mach_msg_type_number_t count = sizeof(*vmstat) / sizeof(integer_t);
- mach_port_t mport = mach_host_self();
-
- ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)vmstat, &count);
- if (ret != KERN_SUCCESS) {
- PyErr_Format(PyExc_RuntimeError,
- "host_statistics() failed: %s", mach_error_string(ret));
- return 0;
- }
- mach_port_deallocate(mach_task_self(), mport);
- return 1;
-}
-
-
-/*
- * Return a Python list of all the PIDs running on the system.
- */
-static PyObject *
-psutil_pids(PyObject *self, PyObject *args)
-{
- kinfo_proc *proclist = NULL;
- kinfo_proc *orig_address = NULL;
- size_t num_processes;
- size_t idx;
- PyObject *pid = NULL;
- PyObject *retlist = PyList_New(0);
-
- if (retlist == NULL)
- return NULL;
-
- if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
- PyErr_SetString(PyExc_RuntimeError,
- "failed to retrieve process list.");
- goto error;
- }
-
- if (num_processes > 0) {
- // save the address of proclist so we can free it later
- orig_address = proclist;
- for (idx = 0; idx < num_processes; idx++) {
- pid = Py_BuildValue("i", proclist->kp_proc.p_pid);
- if (!pid)
- goto error;
- if (PyList_Append(retlist, pid))
- goto error;
- Py_DECREF(pid);
- proclist++;
- }
- free(orig_address);
- }
- return retlist;
-
-error:
- Py_XDECREF(pid);
- Py_DECREF(retlist);
- if (orig_address != NULL)
- free(orig_address);
- return NULL;
-}
-
-
-/*
- * Return process name from kinfo_proc as a Python string.
- */
-static PyObject *
-psutil_proc_name(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("s", kp.kp_proc.p_comm);
-}
-
-
-/*
- * Return process current working directory.
- */
-static PyObject *
-psutil_proc_cwd(PyObject *self, PyObject *args)
-{
- long pid;
- struct proc_vnodepathinfo pathinfo;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- if (! psutil_proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, &pathinfo,
- sizeof(pathinfo)))
- {
- return NULL;
- }
- return Py_BuildValue("s", pathinfo.pvi_cdir.vip_path);
-}
-
-
-/*
- * Return path of the process executable.
- */
-static PyObject *
-psutil_proc_exe(PyObject *self, PyObject *args)
-{
- long pid;
- char buf[PATH_MAX];
- int ret;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- ret = proc_pidpath(pid, &buf, sizeof(buf));
- if (ret == 0) {
- if (! psutil_pid_exists(pid))
- return NoSuchProcess();
- else
- return AccessDenied();
- }
- return Py_BuildValue("s", buf);
-}
-
-
-/*
- * Return process cmdline as a Python list of cmdline arguments.
- */
-static PyObject *
-psutil_proc_cmdline(PyObject *self, PyObject *args)
-{
- long pid;
- PyObject *arglist = NULL;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- // get the commandline, defined in arch/osx/process_info.c
- arglist = psutil_get_arg_list(pid);
- return arglist;
-}
-
-
-/*
- * Return process parent pid from kinfo_proc as a Python integer.
- */
-static PyObject *
-psutil_proc_ppid(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid);
-}
-
-
-/*
- * Return process real uid from kinfo_proc as a Python integer.
- */
-static PyObject *
-psutil_proc_uids(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("lll",
- (long)kp.kp_eproc.e_pcred.p_ruid,
- (long)kp.kp_eproc.e_ucred.cr_uid,
- (long)kp.kp_eproc.e_pcred.p_svuid);
-}
-
-
-/*
- * Return process real group id from ki_comm as a Python integer.
- */
-static PyObject *
-psutil_proc_gids(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("lll",
- (long)kp.kp_eproc.e_pcred.p_rgid,
- (long)kp.kp_eproc.e_ucred.cr_groups[0],
- (long)kp.kp_eproc.e_pcred.p_svgid);
-}
-
-
-/*
- * Return process controlling terminal number as an integer.
- */
-static PyObject *
-psutil_proc_tty_nr(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("i", kp.kp_eproc.e_tdev);
-}
-
-
-/*
- * Return a list of tuples for every process memory maps.
- * 'procstat' cmdline utility has been used as an example.
- */
-static PyObject *
-psutil_proc_memory_maps(PyObject *self, PyObject *args)
-{
- char buf[PATH_MAX];
- char addr_str[34];
- char perms[8];
- int pagesize = getpagesize();
- long pid;
- kern_return_t err = KERN_SUCCESS;
- mach_port_t task = MACH_PORT_NULL;
- uint32_t depth = 1;
- vm_address_t address = 0;
- vm_size_t size = 0;
-
- PyObject *py_tuple = NULL;
- PyObject *py_list = PyList_New(0);
-
- if (py_list == NULL)
- return NULL;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
-
- err = task_for_pid(mach_task_self(), pid, &task);
-
- if (err != KERN_SUCCESS) {
- if (! psutil_pid_exists(pid)) {
- NoSuchProcess();
- }
- else {
- // pid exists, so return AccessDenied error since task_for_pid()
- // failed
- AccessDenied();
- }
- goto error;
- }
-
- while (1) {
- py_tuple = NULL;
- struct vm_region_submap_info_64 info;
- mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
-
- err = vm_region_recurse_64(task, &address, &size, &depth,
- (vm_region_info_64_t)&info, &count);
- if (err == KERN_INVALID_ADDRESS)
- break;
- if (info.is_submap) {
- depth++;
- }
- else {
- // Free/Reset the char[]s to avoid weird paths
- memset(buf, 0, sizeof(buf));
- memset(addr_str, 0, sizeof(addr_str));
- memset(perms, 0, sizeof(perms));
-
- sprintf(addr_str, "%016lx-%016lx", address, address + size);
- sprintf(perms, "%c%c%c/%c%c%c",
- (info.protection & VM_PROT_READ) ? 'r' : '-',
- (info.protection & VM_PROT_WRITE) ? 'w' : '-',
- (info.protection & VM_PROT_EXECUTE) ? 'x' : '-',
- (info.max_protection & VM_PROT_READ) ? 'r' : '-',
- (info.max_protection & VM_PROT_WRITE) ? 'w' : '-',
- (info.max_protection & VM_PROT_EXECUTE) ? 'x' : '-');
-
- err = proc_regionfilename(pid, address, buf, sizeof(buf));
-
- if (info.share_mode == SM_COW && info.ref_count == 1) {
- // Treat single reference SM_COW as SM_PRIVATE
- info.share_mode = SM_PRIVATE;
- }
-
- if (strlen(buf) == 0) {
- switch (info.share_mode) {
- // case SM_LARGE_PAGE:
- // Treat SM_LARGE_PAGE the same as SM_PRIVATE
- // since they are not shareable and are wired.
- case SM_COW:
- strcpy(buf, "[cow]");
- break;
- case SM_PRIVATE:
- strcpy(buf, "[prv]");
- break;
- case SM_EMPTY:
- strcpy(buf, "[nul]");
- break;
- case SM_SHARED:
- case SM_TRUESHARED:
- strcpy(buf, "[shm]");
- break;
- case SM_PRIVATE_ALIASED:
- strcpy(buf, "[ali]");
- break;
- case SM_SHARED_ALIASED:
- strcpy(buf, "[s/a]");
- break;
- default:
- strcpy(buf, "[???]");
- }
- }
-
- py_tuple = Py_BuildValue(
- "sssIIIIIH",
- addr_str, // "start-end"address
- perms, // "rwx" permissions
- buf, // path
- info.pages_resident * pagesize, // rss
- info.pages_shared_now_private * pagesize, // private
- info.pages_swapped_out * pagesize, // swapped
- info.pages_dirtied * pagesize, // dirtied
- info.ref_count, // ref count
- info.shadow_depth // shadow depth
- );
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_list, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
-
- // increment address for the next map/file
- address += size;
- }
-
- if (task != MACH_PORT_NULL)
- mach_port_deallocate(mach_task_self(), task);
-
- return py_list;
-
-error:
- if (task != MACH_PORT_NULL)
- mach_port_deallocate(mach_task_self(), task);
- Py_XDECREF(py_tuple);
- Py_DECREF(py_list);
- return NULL;
-}
-
-
-/*
- * Return the number of logical CPUs in the system.
- * XXX this could be shared with BSD.
- */
-static PyObject *
-psutil_cpu_count_logical(PyObject *self, PyObject *args)
-{
- int mib[2];
- int ncpu;
- size_t len;
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(ncpu);
-
- if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", ncpu);
-}
-
-
-/*
- * Return the number of physical CPUs in the system.
- */
-static PyObject *
-psutil_cpu_count_phys(PyObject *self, PyObject *args)
-{
- int num;
- size_t size = sizeof(int);
-
- if (sysctlbyname("hw.physicalcpu", &num, &size, NULL, 0))
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", num);
-}
-
-
-#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
-
-/*
- * Return a Python tuple (user_time, kernel_time)
- */
-static PyObject *
-psutil_proc_cpu_times(PyObject *self, PyObject *args)
-{
- long pid;
- struct proc_taskinfo pti;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
- return NULL;
- return Py_BuildValue("(dd)",
- (float)pti.pti_total_user / 1000000000.0,
- (float)pti.pti_total_system / 1000000000.0);
-}
-
-
-/*
- * Return a Python float indicating the process create time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_proc_create_time(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime));
-}
-
-
-/*
- * Return extended memory info about a process.
- */
-static PyObject *
-psutil_proc_memory_info(PyObject *self, PyObject *args)
-{
- long pid;
- struct proc_taskinfo pti;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
- return NULL;
- // Note: determining other memory stats on OSX is a mess:
- // http://www.opensource.apple.com/source/top/top-67/libtop.c?txt
- // I just give up...
- // struct proc_regioninfo pri;
- // psutil_proc_pidinfo(pid, PROC_PIDREGIONINFO, &pri, sizeof(pri))
- return Py_BuildValue(
- "(KKkk)",
- pti.pti_resident_size, // resident memory size (rss)
- pti.pti_virtual_size, // virtual memory size (vms)
- pti.pti_faults, // number of page faults (pages)
- pti.pti_pageins // number of actual pageins (pages)
- );
-}
-
-
-/*
- * Return number of threads used by process as a Python integer.
- */
-static PyObject *
-psutil_proc_num_threads(PyObject *self, PyObject *args)
-{
- long pid;
- struct proc_taskinfo pti;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
- return NULL;
- return Py_BuildValue("k", pti.pti_threadnum);
-}
-
-
-/*
- * Return the number of context switches performed by process.
- */
-static PyObject *
-psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
-{
- long pid;
- struct proc_taskinfo pti;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
- return NULL;
- // unvoluntary value seems not to be available;
- // pti.pti_csw probably refers to the sum of the two (getrusage()
- // numbers seems to confirm this theory).
- return Py_BuildValue("ki", pti.pti_csw, 0);
-}
-
-
-/*
- * Return system virtual memory stats
- */
-static PyObject *
-psutil_virtual_mem(PyObject *self, PyObject *args)
-{
-
- int mib[2];
- uint64_t total;
- size_t len = sizeof(total);
- vm_statistics_data_t vm;
- int pagesize = getpagesize();
- // physical mem
- mib[0] = CTL_HW;
- mib[1] = HW_MEMSIZE;
-
- if (sysctl(mib, 2, &total, &len, NULL, 0)) {
- if (errno != 0)
- PyErr_SetFromErrno(PyExc_OSError);
- else
- PyErr_Format(PyExc_RuntimeError, "sysctl(HW_MEMSIZE) failed");
- return NULL;
- }
-
- // vm
- if (!psutil_sys_vminfo(&vm))
- return NULL;
-
- return Py_BuildValue(
- "KKKKK",
- total,
- (unsigned long long) vm.active_count * pagesize,
- (unsigned long long) vm.inactive_count * pagesize,
- (unsigned long long) vm.wire_count * pagesize,
- (unsigned long long) vm.free_count * pagesize
- );
-}
-
-
-/*
- * Return stats about swap memory.
- */
-static PyObject *
-psutil_swap_mem(PyObject *self, PyObject *args)
-{
- int mib[2];
- size_t size;
- struct xsw_usage totals;
- vm_statistics_data_t vmstat;
- int pagesize = getpagesize();
-
- mib[0] = CTL_VM;
- mib[1] = VM_SWAPUSAGE;
- size = sizeof(totals);
- if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) {
- if (errno != 0)
- PyErr_SetFromErrno(PyExc_OSError);
- else
- PyErr_Format(PyExc_RuntimeError, "sysctl(VM_SWAPUSAGE) failed");
- return NULL;
- }
- if (!psutil_sys_vminfo(&vmstat))
- return NULL;
-
- return Py_BuildValue(
- "LLLKK",
- totals.xsu_total,
- totals.xsu_used,
- totals.xsu_avail,
- (unsigned long long)vmstat.pageins * pagesize,
- (unsigned long long)vmstat.pageouts * pagesize);
-}
-
-
-/*
- * Return a Python tuple representing user, kernel and idle CPU times
- */
-static PyObject *
-psutil_cpu_times(PyObject *self, PyObject *args)
-{
- mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
- kern_return_t error;
- host_cpu_load_info_data_t r_load;
-
- mach_port_t host_port = mach_host_self();
- error = host_statistics(host_port, HOST_CPU_LOAD_INFO,
- (host_info_t)&r_load, &count);
- if (error != KERN_SUCCESS)
- return PyErr_Format(PyExc_RuntimeError,
- "Error in host_statistics(): %s",
- mach_error_string(error));
- mach_port_deallocate(mach_task_self(), host_port);
-
- return Py_BuildValue(
- "(dddd)",
- (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
- );
-}
-
-
-/*
- * Return a Python list of tuple representing per-cpu times
- */
-static PyObject *
-psutil_per_cpu_times(PyObject *self, PyObject *args)
-{
- natural_t cpu_count;
- processor_info_array_t info_array;
- mach_msg_type_number_t info_count;
- kern_return_t error;
- processor_cpu_load_info_data_t *cpu_load_info = NULL;
- int i, ret;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_cputime = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- mach_port_t host_port = mach_host_self();
- error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO,
- &cpu_count, &info_array, &info_count);
- if (error != KERN_SUCCESS) {
- PyErr_Format(PyExc_RuntimeError, "Error in host_processor_info(): %s",
- mach_error_string(error));
- goto error;
- }
- mach_port_deallocate(mach_task_self(), host_port);
-
- cpu_load_info = (processor_cpu_load_info_data_t *) info_array;
-
- for (i = 0; i < cpu_count; i++) {
- py_cputime = Py_BuildValue(
- "(dddd)",
- (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK,
- (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
- (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
- (double)cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
- );
- if (!py_cputime)
- goto error;
- if (PyList_Append(py_retlist, py_cputime))
- goto error;
- Py_DECREF(py_cputime);
- }
-
- ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
- info_count * sizeof(int));
- if (ret != KERN_SUCCESS)
- PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
- return py_retlist;
-
-error:
- Py_XDECREF(py_cputime);
- Py_DECREF(py_retlist);
- if (cpu_load_info != NULL) {
- ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
- info_count * sizeof(int));
- if (ret != KERN_SUCCESS)
- PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
- }
- return NULL;
-}
-
-
-/*
- * Return a Python float indicating the system boot time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_boot_time(PyObject *self, PyObject *args)
-{
- // fetch sysctl "kern.boottime"
- static int request[2] = { CTL_KERN, KERN_BOOTTIME };
- struct timeval result;
- size_t result_len = sizeof result;
- time_t boot_time = 0;
-
- if (sysctl(request, 2, &result, &result_len, NULL, 0) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
- boot_time = result.tv_sec;
- return Py_BuildValue("f", (float)boot_time);
-}
-
-
-/*
- * Return a list of tuples including device, mount point and fs type
- * for all partitions mounted on the system.
- */
-static PyObject *
-psutil_disk_partitions(PyObject *self, PyObject *args)
-{
- int num;
- int i;
- long len;
- uint64_t flags;
- char opts[400];
- struct statfs *fs = NULL;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- // get the number of mount points
- Py_BEGIN_ALLOW_THREADS
- num = getfsstat(NULL, 0, MNT_NOWAIT);
- Py_END_ALLOW_THREADS
- if (num == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- len = sizeof(*fs) * num;
- fs = malloc(len);
- if (fs == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- Py_BEGIN_ALLOW_THREADS
- num = getfsstat(fs, len, MNT_NOWAIT);
- Py_END_ALLOW_THREADS
- if (num == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- for (i = 0; i < num; i++) {
- opts[0] = 0;
- flags = fs[i].f_flags;
-
- // see sys/mount.h
- if (flags & MNT_RDONLY)
- strlcat(opts, "ro", sizeof(opts));
- else
- strlcat(opts, "rw", sizeof(opts));
- if (flags & MNT_SYNCHRONOUS)
- strlcat(opts, ",sync", sizeof(opts));
- if (flags & MNT_NOEXEC)
- strlcat(opts, ",noexec", sizeof(opts));
- if (flags & MNT_NOSUID)
- strlcat(opts, ",nosuid", sizeof(opts));
- if (flags & MNT_UNION)
- strlcat(opts, ",union", sizeof(opts));
- if (flags & MNT_ASYNC)
- strlcat(opts, ",async", sizeof(opts));
- if (flags & MNT_EXPORTED)
- strlcat(opts, ",exported", sizeof(opts));
- if (flags & MNT_QUARANTINE)
- strlcat(opts, ",quarantine", sizeof(opts));
- if (flags & MNT_LOCAL)
- strlcat(opts, ",local", sizeof(opts));
- if (flags & MNT_QUOTA)
- strlcat(opts, ",quota", sizeof(opts));
- if (flags & MNT_ROOTFS)
- strlcat(opts, ",rootfs", sizeof(opts));
- if (flags & MNT_DOVOLFS)
- strlcat(opts, ",dovolfs", sizeof(opts));
- if (flags & MNT_DONTBROWSE)
- strlcat(opts, ",dontbrowse", sizeof(opts));
- if (flags & MNT_IGNORE_OWNERSHIP)
- strlcat(opts, ",ignore-ownership", sizeof(opts));
- if (flags & MNT_AUTOMOUNTED)
- strlcat(opts, ",automounted", sizeof(opts));
- if (flags & MNT_JOURNALED)
- strlcat(opts, ",journaled", sizeof(opts));
- if (flags & MNT_NOUSERXATTR)
- strlcat(opts, ",nouserxattr", sizeof(opts));
- if (flags & MNT_DEFWRITE)
- strlcat(opts, ",defwrite", sizeof(opts));
- if (flags & MNT_MULTILABEL)
- strlcat(opts, ",multilabel", sizeof(opts));
- if (flags & MNT_NOATIME)
- strlcat(opts, ",noatime", sizeof(opts));
- if (flags & MNT_UPDATE)
- strlcat(opts, ",update", sizeof(opts));
- if (flags & MNT_RELOAD)
- strlcat(opts, ",reload", sizeof(opts));
- if (flags & MNT_FORCE)
- strlcat(opts, ",force", sizeof(opts));
- if (flags & MNT_CMDFLAGS)
- strlcat(opts, ",cmdflags", sizeof(opts));
-
- py_tuple = Py_BuildValue(
- "(ssss)", fs[i].f_mntfromname, // device
- fs[i].f_mntonname, // mount point
- fs[i].f_fstypename, // fs type
- opts); // options
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
-
- free(fs);
- return py_retlist;
-
-error:
- Py_XDECREF(py_tuple);
- Py_DECREF(py_retlist);
- if (fs != NULL)
- free(fs);
- return NULL;
-}
-
-
-/*
- * Return process status as a Python integer.
- */
-static PyObject *
-psutil_proc_status(PyObject *self, PyObject *args)
-{
- long pid;
- struct kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (psutil_get_kinfo_proc(pid, &kp) == -1)
- return NULL;
- return Py_BuildValue("i", (int)kp.kp_proc.p_stat);
-}
-
-
-/*
- * Return process threads
- */
-static PyObject *
-psutil_proc_threads(PyObject *self, PyObject *args)
-{
- long pid;
- int err, j, ret;
- kern_return_t kr;
- unsigned int info_count = TASK_BASIC_INFO_COUNT;
- mach_port_t task = MACH_PORT_NULL;
- struct task_basic_info tasks_info;
- thread_act_port_array_t thread_list = NULL;
- thread_info_data_t thinfo_basic;
- thread_basic_info_t basic_info_th;
- mach_msg_type_number_t thread_count, thread_info_count;
-
- PyObject *retList = PyList_New(0);
- PyObject *pyTuple = NULL;
-
- if (retList == NULL)
- return NULL;
-
- // the argument passed should be a process id
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
-
- // task_for_pid() requires special privileges
- err = task_for_pid(mach_task_self(), pid, &task);
- if (err != KERN_SUCCESS) {
- if (! psutil_pid_exists(pid))
- NoSuchProcess();
- else
- AccessDenied();
- goto error;
- }
-
- info_count = TASK_BASIC_INFO_COUNT;
- err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info,
- &info_count);
- if (err != KERN_SUCCESS) {
- // errcode 4 is "invalid argument" (access denied)
- if (err == 4) {
- AccessDenied();
- }
- else {
- // otherwise throw a runtime error with appropriate error code
- PyErr_Format(PyExc_RuntimeError,
- "task_info(TASK_BASIC_INFO) failed");
- }
- goto error;
- }
-
- err = task_threads(task, &thread_list, &thread_count);
- if (err != KERN_SUCCESS) {
- PyErr_Format(PyExc_RuntimeError, "task_threads() failed");
- goto error;
- }
-
- for (j = 0; j < thread_count; j++) {
- pyTuple = NULL;
- thread_info_count = THREAD_INFO_MAX;
- kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
- (thread_info_t)thinfo_basic, &thread_info_count);
- if (kr != KERN_SUCCESS) {
- PyErr_Format(PyExc_RuntimeError,
- "thread_info() with flag THREAD_BASIC_INFO failed");
- goto error;
- }
-
- basic_info_th = (thread_basic_info_t)thinfo_basic;
- pyTuple = Py_BuildValue(
- "Iff",
- j + 1,
- (float)basic_info_th->user_time.microseconds / 1000000.0,
- (float)basic_info_th->system_time.microseconds / 1000000.0
- );
- if (!pyTuple)
- goto error;
- if (PyList_Append(retList, pyTuple))
- goto error;
- Py_DECREF(pyTuple);
- }
-
- ret = vm_deallocate(task, (vm_address_t)thread_list,
- thread_count * sizeof(int));
- if (ret != KERN_SUCCESS)
- PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
-
- mach_port_deallocate(mach_task_self(), task);
-
- return retList;
-
-error:
- if (task != MACH_PORT_NULL)
- mach_port_deallocate(mach_task_self(), task);
- Py_XDECREF(pyTuple);
- Py_DECREF(retList);
- if (thread_list != NULL) {
- ret = vm_deallocate(task, (vm_address_t)thread_list,
- thread_count * sizeof(int));
- if (ret != KERN_SUCCESS)
- PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
- }
- return NULL;
-}
-
-
-/*
- * Return process open files as a Python tuple.
- * References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
- * - /usr/include/sys/proc_info.h
- */
-static PyObject *
-psutil_proc_open_files(PyObject *self, PyObject *args)
-{
- long pid;
- int pidinfo_result;
- int iterations;
- int i;
- int nb;
-
- struct proc_fdinfo *fds_pointer = NULL;
- struct proc_fdinfo *fdp_pointer;
- struct vnode_fdinfowithpath vi;
-
- PyObject *retList = PyList_New(0);
- PyObject *tuple = NULL;
-
- if (retList == NULL)
- return NULL;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
-
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
- if (pidinfo_result <= 0) {
- // may be be ignored later if errno != 0
- PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDLISTFDS) failed");
- goto error;
- }
-
- fds_pointer = malloc(pidinfo_result);
- if (fds_pointer == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
- pidinfo_result);
- if (pidinfo_result <= 0) {
- // may be be ignored later if errno != 0
- PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDLISTFDS) failed");
- goto error;
- }
-
- iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
-
- for (i = 0; i < iterations; i++) {
- tuple = NULL;
- fdp_pointer = &fds_pointer[i];
-
- if (fdp_pointer->proc_fdtype == PROX_FDTYPE_VNODE)
- {
- nb = proc_pidfdinfo(pid,
- fdp_pointer->proc_fd,
- PROC_PIDFDVNODEPATHINFO,
- &vi,
- sizeof(vi));
-
- // --- errors checking
- if (nb <= 0) {
- if ((errno == ENOENT) || (errno == EBADF)) {
- // no such file or directory or bad file descriptor;
- // let's assume the file has been closed or removed
- continue;
- }
- // may be be ignored later if errno != 0
- PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
- goto error;
- }
- if (nb < sizeof(vi)) {
- PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
- "(buffer mismatch)");
- goto error;
- }
- // --- /errors checking
-
- // --- construct python list
- tuple = Py_BuildValue("(si)",
- vi.pvip.vip_path,
- (int)fdp_pointer->proc_fd);
- if (!tuple)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- // --- /construct python list
- }
- }
-
- free(fds_pointer);
- return retList;
-
-error:
- Py_XDECREF(tuple);
- Py_DECREF(retList);
- if (fds_pointer != NULL)
- free(fds_pointer);
- if (errno != 0)
- return PyErr_SetFromErrno(PyExc_OSError);
- else if (! psutil_pid_exists(pid))
- return NoSuchProcess();
- else
- return NULL; // exception has already been set earlier
-}
-
-
-// a signaler for connections without an actual status
-static int PSUTIL_CONN_NONE = 128;
-
-/*
- * Return process TCP and UDP connections as a list of tuples.
- * References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
- * - /usr/include/sys/proc_info.h
- */
-static PyObject *
-psutil_proc_connections(PyObject *self, PyObject *args)
-{
- long pid;
- int pidinfo_result;
- int iterations;
- int i;
- int nb;
-
- struct proc_fdinfo *fds_pointer = NULL;
- struct proc_fdinfo *fdp_pointer;
- struct socket_fdinfo si;
-
- PyObject *retList = PyList_New(0);
- PyObject *tuple = NULL;
- PyObject *laddr = NULL;
- PyObject *raddr = NULL;
- PyObject *af_filter = NULL;
- PyObject *type_filter = NULL;
-
- if (retList == NULL)
- return NULL;
-
- if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
- goto error;
-
- if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
- PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
- goto error;
- }
-
- if (pid == 0)
- return retList;
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
- if (pidinfo_result <= 0)
- goto error;
-
- fds_pointer = malloc(pidinfo_result);
- if (fds_pointer == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
- pidinfo_result);
-
- if (pidinfo_result <= 0)
- goto error;
- iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
-
- for (i = 0; i < iterations; i++) {
- tuple = NULL;
- laddr = NULL;
- raddr = NULL;
- errno = 0;
- fdp_pointer = &fds_pointer[i];
-
- if (fdp_pointer->proc_fdtype == PROX_FDTYPE_SOCKET)
- {
- nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd,
- PROC_PIDFDSOCKETINFO, &si, sizeof(si));
-
- // --- errors checking
- if (nb <= 0) {
- if (errno == EBADF) {
- // let's assume socket has been closed
- continue;
- }
- if (errno != 0)
- PyErr_SetFromErrno(PyExc_OSError);
- else
- PyErr_Format(
- PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
- goto error;
- }
- if (nb < sizeof(si)) {
- PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
- "(buffer mismatch)");
- goto error;
- }
- // --- /errors checking
-
- //
- int fd, family, type, lport, rport, state;
- char lip[200], rip[200];
- int inseq;
- PyObject *_family;
- PyObject *_type;
-
- fd = (int)fdp_pointer->proc_fd;
- family = si.psi.soi_family;
- type = si.psi.soi_type;
-
- // apply filters
- _family = PyLong_FromLong((long)family);
- inseq = PySequence_Contains(af_filter, _family);
- Py_DECREF(_family);
- if (inseq == 0)
- continue;
- _type = PyLong_FromLong((long)type);
- inseq = PySequence_Contains(type_filter, _type);
- Py_DECREF(_type);
- if (inseq == 0)
- continue;
-
- if (errno != 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- if ((family == AF_INET) || (family == AF_INET6)) {
- if (family == AF_INET) {
- inet_ntop(AF_INET,
- &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
- insi_laddr.ina_46.i46a_addr4,
- lip,
- sizeof(lip));
- inet_ntop(AF_INET,
- &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr. \
- ina_46.i46a_addr4,
- rip,
- sizeof(rip));
- }
- else {
- inet_ntop(AF_INET6,
- &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
- insi_laddr.ina_6,
- lip, sizeof(lip));
- inet_ntop(AF_INET6,
- &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
- insi_faddr.ina_6,
- rip, sizeof(rip));
- }
-
- // check for inet_ntop failures
- if (errno != 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- lport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
- rport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
- if (type == SOCK_STREAM)
- state = (int)si.psi.soi_proto.pri_tcp.tcpsi_state;
- else
- state = PSUTIL_CONN_NONE;
-
- laddr = Py_BuildValue("(si)", lip, lport);
- if (!laddr)
- goto error;
- if (rport != 0)
- raddr = Py_BuildValue("(si)", rip, rport);
- else
- raddr = Py_BuildValue("()");
- if (!raddr)
- goto error;
-
- // construct the python list
- tuple = Py_BuildValue("(iiiNNi)", fd, family, type, laddr,
- raddr, state);
- if (!tuple)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- else if (family == AF_UNIX) {
- // construct the python list
- tuple = Py_BuildValue(
- "(iiissi)",
- fd, family, type,
- si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path,
- si.psi.soi_proto.pri_un.unsi_caddr.ua_sun.sun_path,
- PSUTIL_CONN_NONE);
- if (!tuple)
- goto error;
- if (PyList_Append(retList, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- }
- }
-
- free(fds_pointer);
- return retList;
-
-error:
- Py_XDECREF(tuple);
- Py_XDECREF(laddr);
- Py_XDECREF(raddr);
- Py_DECREF(retList);
-
- if (fds_pointer != NULL)
- free(fds_pointer);
- if (errno != 0)
- return PyErr_SetFromErrno(PyExc_OSError);
- else if (! psutil_pid_exists(pid))
- return NoSuchProcess();
- else
- return PyErr_Format(PyExc_RuntimeError,
- "proc_pidinfo(PROC_PIDLISTFDS) failed");
-}
-
-
-/*
- * Return number of file descriptors opened by process.
- */
-static PyObject *
-psutil_proc_num_fds(PyObject *self, PyObject *args)
-{
- long pid;
- int pidinfo_result;
- int num;
- struct proc_fdinfo *fds_pointer;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
- if (pidinfo_result <= 0)
- return PyErr_SetFromErrno(PyExc_OSError);
-
- fds_pointer = malloc(pidinfo_result);
- if (fds_pointer == NULL)
- return PyErr_NoMemory();
- pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
- pidinfo_result);
- if (pidinfo_result <= 0) {
- free(fds_pointer);
- return PyErr_SetFromErrno(PyExc_OSError);
- }
-
- num = (pidinfo_result / PROC_PIDLISTFD_SIZE);
- free(fds_pointer);
- return Py_BuildValue("i", num);
-}
-
-
-/*
- * Return a Python list of named tuples with overall network I/O information
- */
-static PyObject *
-psutil_net_io_counters(PyObject *self, PyObject *args)
-{
- char *buf = NULL, *lim, *next;
- struct if_msghdr *ifm;
- int mib[6];
- size_t len;
- PyObject *py_retdict = PyDict_New();
- PyObject *py_ifc_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
-
- mib[0] = CTL_NET; // networking subsystem
- mib[1] = PF_ROUTE; // type of information
- mib[2] = 0; // protocol (IPPROTO_xxx)
- mib[3] = 0; // address family
- mib[4] = NET_RT_IFLIST2; // operation
- mib[5] = 0;
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- buf = malloc(len);
- if (buf == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- lim = buf + len;
-
- for (next = buf; next < lim; ) {
- ifm = (struct if_msghdr *)next;
- next += ifm->ifm_msglen;
-
- if (ifm->ifm_type == RTM_IFINFO2) {
- py_ifc_info = NULL;
- struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
- struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
- char ifc_name[32];
-
- strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
- ifc_name[sdl->sdl_nlen] = 0;
-
- py_ifc_info = Py_BuildValue(
- "(KKKKKKKi)",
- if2m->ifm_data.ifi_obytes,
- if2m->ifm_data.ifi_ibytes,
- if2m->ifm_data.ifi_opackets,
- if2m->ifm_data.ifi_ipackets,
- if2m->ifm_data.ifi_ierrors,
- if2m->ifm_data.ifi_oerrors,
- if2m->ifm_data.ifi_iqdrops,
- 0); // dropout not supported
-
- if (!py_ifc_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info))
- goto error;
- Py_DECREF(py_ifc_info);
- }
- else {
- continue;
- }
- }
-
- free(buf);
- return py_retdict;
-
-error:
- Py_XDECREF(py_ifc_info);
- Py_DECREF(py_retdict);
- if (buf != NULL)
- free(buf);
- return NULL;
-}
-
-
-/*
- * Return a Python dict of tuples for disk I/O information
- */
-static PyObject *
-psutil_disk_io_counters(PyObject *self, PyObject *args)
-{
- CFDictionaryRef parent_dict;
- CFDictionaryRef props_dict;
- CFDictionaryRef stats_dict;
- io_registry_entry_t parent;
- io_registry_entry_t disk;
- io_iterator_t disk_list;
- PyObject *py_retdict = PyDict_New();
- PyObject *py_disk_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
-
- // Get list of disks
- if (IOServiceGetMatchingServices(kIOMasterPortDefault,
- IOServiceMatching(kIOMediaClass),
- &disk_list) != kIOReturnSuccess) {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the list of disks.");
- goto error;
- }
-
- // Iterate over disks
- while ((disk = IOIteratorNext(disk_list)) != 0) {
- py_disk_info = NULL;
- parent_dict = NULL;
- props_dict = NULL;
- stats_dict = NULL;
-
- if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent)
- != kIOReturnSuccess) {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the disk's parent.");
- IOObjectRelease(disk);
- goto error;
- }
-
- if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) {
- if (IORegistryEntryCreateCFProperties(
- disk,
- (CFMutableDictionaryRef *) &parent_dict,
- kCFAllocatorDefault,
- kNilOptions
- ) != kIOReturnSuccess)
- {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the parent's properties.");
- IOObjectRelease(disk);
- IOObjectRelease(parent);
- goto error;
- }
-
- if (IORegistryEntryCreateCFProperties(
- parent,
- (CFMutableDictionaryRef *) &props_dict,
- kCFAllocatorDefault,
- kNilOptions
- ) != kIOReturnSuccess)
- {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the disk properties.");
- CFRelease(props_dict);
- IOObjectRelease(disk);
- IOObjectRelease(parent);
- goto error;
- }
-
- const int kMaxDiskNameSize = 64;
- CFStringRef disk_name_ref = (CFStringRef)CFDictionaryGetValue(
- parent_dict, CFSTR(kIOBSDNameKey));
- char disk_name[kMaxDiskNameSize];
-
- CFStringGetCString(disk_name_ref,
- disk_name,
- kMaxDiskNameSize,
- CFStringGetSystemEncoding());
-
- stats_dict = (CFDictionaryRef)CFDictionaryGetValue(
- props_dict, CFSTR(kIOBlockStorageDriverStatisticsKey));
-
- if (stats_dict == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "Unable to get disk stats.");
- goto error;
- }
-
- CFNumberRef number;
- int64_t reads = 0;
- int64_t writes = 0;
- int64_t read_bytes = 0;
- int64_t write_bytes = 0;
- int64_t read_time = 0;
- int64_t write_time = 0;
-
- // Get disk reads/writes
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsReadsKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &reads);
- }
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsWritesKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &writes);
- }
-
- // Get disk bytes read/written
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &read_bytes);
- }
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &write_bytes);
- }
-
- // Get disk time spent reading/writing (nanoseconds)
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &read_time);
- }
- if ((number = (CFNumberRef)CFDictionaryGetValue(
- stats_dict,
- CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey))))
- {
- CFNumberGetValue(number, kCFNumberSInt64Type, &write_time);
- }
-
- // Read/Write time on OS X comes back in nanoseconds and in psutil
- // we've standardized on milliseconds so do the conversion.
- py_disk_info = Py_BuildValue(
- "(KKKKKK)",
- reads,
- writes,
- read_bytes,
- write_bytes,
- read_time / 1000 / 1000,
- write_time / 1000 / 1000);
- if (!py_disk_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
- goto error;
- Py_DECREF(py_disk_info);
-
- CFRelease(parent_dict);
- IOObjectRelease(parent);
- CFRelease(props_dict);
- IOObjectRelease(disk);
- }
- }
-
- IOObjectRelease (disk_list);
-
- return py_retdict;
-
-error:
- Py_XDECREF(py_disk_info);
- Py_DECREF(py_retdict);
- return NULL;
-}
-
-
-/*
- * Return currently connected users as a list of tuples.
- */
-static PyObject *
-psutil_users(PyObject *self, PyObject *args)
-{
- struct utmpx *utx;
- PyObject *ret_list = PyList_New(0);
- PyObject *tuple = NULL;
-
- if (ret_list == NULL)
- return NULL;
- while ((utx = getutxent()) != NULL) {
- if (utx->ut_type != USER_PROCESS)
- continue;
- tuple = Py_BuildValue(
- "(sssf)",
- utx->ut_user, // username
- utx->ut_line, // tty
- utx->ut_host, // hostname
- (float)utx->ut_tv.tv_sec // start time
- );
- if (!tuple) {
- endutxent();
- goto error;
- }
- if (PyList_Append(ret_list, tuple)) {
- endutxent();
- goto error;
- }
- Py_DECREF(tuple);
- }
-
- endutxent();
- return ret_list;
-
-error:
- Py_XDECREF(tuple);
- Py_DECREF(ret_list);
- return NULL;
-}
-
-
-/*
- * define the psutil C module methods and initialize the module.
- */
-static PyMethodDef
-PsutilMethods[] =
-{
- // --- per-process functions
-
- {"proc_name", psutil_proc_name, METH_VARARGS,
- "Return process name"},
- {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
- "Return process cmdline as a list of cmdline arguments"},
- {"proc_exe", psutil_proc_exe, METH_VARARGS,
- "Return path of the process executable"},
- {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
- "Return process current working directory."},
- {"proc_ppid", psutil_proc_ppid, METH_VARARGS,
- "Return process ppid as an integer"},
- {"proc_uids", psutil_proc_uids, METH_VARARGS,
- "Return process real user id as an integer"},
- {"proc_gids", psutil_proc_gids, METH_VARARGS,
- "Return process real group id as an integer"},
- {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
- "Return tuple of user/kern time for the given PID"},
- {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
- "Return a float indicating the process create time expressed in "
- "seconds since the epoch"},
- {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
- "Return memory information about a process"},
- {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS,
- "Return number of threads used by process"},
- {"proc_status", psutil_proc_status, METH_VARARGS,
- "Return process status as an integer"},
- {"proc_threads", psutil_proc_threads, METH_VARARGS,
- "Return process threads as a list of tuples"},
- {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
- "Return files opened by process as a list of tuples"},
- {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS,
- "Return the number of fds opened by process."},
- {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
- "Return the number of context switches performed by process"},
- {"proc_connections", psutil_proc_connections, METH_VARARGS,
- "Get process TCP and UDP connections as a list of tuples"},
- {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS,
- "Return process tty number as an integer"},
- {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
- "Return a list of tuples for every process's memory map"},
-
- // --- system-related functions
-
- {"pids", psutil_pids, METH_VARARGS,
- "Returns a list of PIDs currently running on the system"},
- {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
- "Return number of logical CPUs on the system"},
- {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
- "Return number of physical CPUs on the system"},
- {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
- "Return system virtual memory stats"},
- {"swap_mem", psutil_swap_mem, METH_VARARGS,
- "Return stats about swap memory, in bytes"},
- {"cpu_times", psutil_cpu_times, METH_VARARGS,
- "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
- {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
- "Return system per-cpu times as a list of tuples"},
- {"boot_time", psutil_boot_time, METH_VARARGS,
- "Return the system boot time expressed in seconds since the epoch."},
- {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
- "Return a list of tuples including device, mount point and "
- "fs type for all partitions mounted on the system."},
- {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
- "Return dict of tuples of networks I/O information."},
- {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
- "Return dict of tuples of disks I/O information."},
- {"users", psutil_users, METH_VARARGS,
- "Return currently connected users as a list of tuples"},
-
- {NULL, NULL, 0, NULL}
-};
-
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int
-psutil_osx_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int
-psutil_osx_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_osx",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_osx_traverse,
- psutil_osx_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_osx(void)
-
-#else
-#define INITERROR return
-
-void
-init_psutil_osx(void)
-#endif
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_osx", PsutilMethods);
-#endif
- PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
- // process status constants, defined in:
- // http://fxr.watson.org/fxr/source/bsd/sys/proc.h?v=xnu-792.6.70#L149
- PyModule_AddIntConstant(module, "SIDL", SIDL);
- PyModule_AddIntConstant(module, "SRUN", SRUN);
- PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
- PyModule_AddIntConstant(module, "SSTOP", SSTOP);
- PyModule_AddIntConstant(module, "SZOMB", SZOMB);
- // connection status constants
- PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
- PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
- PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
- PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
- PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
- PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
- PyModule_AddIntConstant(module, "TCPS_SYN_RECEIVED", TCPS_SYN_RECEIVED);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
- PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
- PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
- PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
-
- if (module == NULL)
- INITERROR;
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_osx.h b/python/psutil/psutil/_psutil_osx.h
deleted file mode 100644
index 907a8e537..000000000
--- a/python/psutil/psutil/_psutil_osx.h
+++ /dev/null
@@ -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);
diff --git a/python/psutil/psutil/_psutil_posix.c b/python/psutil/psutil/_psutil_posix.c
deleted file mode 100644
index 183dab0e1..000000000
--- a/python/psutil/psutil/_psutil_posix.c
+++ /dev/null
@@ -1,531 +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.
- *
- * Functions specific to all POSIX compliant platforms.
- */
-
-#include <Python.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <ifaddrs.h>
-
-#ifdef __linux
-#include <netdb.h>
-#include <linux/if_packet.h>
-#endif // end linux
-
-#if defined(__FreeBSD__) || defined(__APPLE__)
-#include <netdb.h>
-#include <netinet/in.h>
-#include <net/if_dl.h>
-#endif
-
-#if defined(__sun)
-#include <netdb.h>
-#endif
-
-#include "_psutil_posix.h"
-
-
-/*
- * Given a PID return process priority as a Python integer.
- */
-static PyObject *
-psutil_posix_getpriority(PyObject *self, PyObject *args)
-{
- long pid;
- int priority;
- errno = 0;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- priority = getpriority(PRIO_PROCESS, pid);
- if (errno != 0)
- return PyErr_SetFromErrno(PyExc_OSError);
- return Py_BuildValue("i", priority);
-}
-
-
-/*
- * Given a PID and a value change process priority.
- */
-static PyObject *
-psutil_posix_setpriority(PyObject *self, PyObject *args)
-{
- long pid;
- int priority;
- int retval;
-
- if (! PyArg_ParseTuple(args, "li", &pid, &priority))
- return NULL;
- retval = setpriority(PRIO_PROCESS, pid, priority);
- if (retval == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Translate a sockaddr struct into a Python string.
- * Return None if address family is not AF_INET* or AF_PACKET.
- */
-static PyObject *
-psutil_convert_ipaddr(struct sockaddr *addr, int family)
-{
- char buf[NI_MAXHOST];
- int err;
- int addrlen;
- int n;
- size_t len;
- const char *data;
- char *ptr;
-
- if (addr == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- else if (family == AF_INET || family == AF_INET6) {
- if (family == AF_INET)
- addrlen = sizeof(struct sockaddr_in);
- else
- addrlen = sizeof(struct sockaddr_in6);
- err = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
- NI_NUMERICHOST);
- if (err != 0) {
- // XXX we get here on FreeBSD when processing 'lo' / AF_INET6
- // broadcast. Not sure what to do other than returning None.
- // ifconfig does not show anything BTW.
- //PyErr_Format(PyExc_RuntimeError, gai_strerror(err));
- //return NULL;
- Py_INCREF(Py_None);
- return Py_None;
- }
- else {
- return Py_BuildValue("s", buf);
- }
- }
-#ifdef __linux
- else if (family == AF_PACKET) {
- struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
- len = lladdr->sll_halen;
- data = (const char *)lladdr->sll_addr;
- }
-#endif
-#if defined(__FreeBSD__) || defined(__APPLE__)
- else if (addr->sa_family == AF_LINK) {
- // Note: prior to Python 3.4 socket module does not expose
- // AF_LINK so we'll do.
- struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
- len = dladdr->sdl_alen;
- data = LLADDR(dladdr);
- }
-#endif
- else {
- // unknown family
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- // AF_PACKET or AF_LINK
- if (len > 0) {
- ptr = buf;
- for (n = 0; n < len; ++n) {
- sprintf(ptr, "%02x:", data[n] & 0xff);
- ptr += 3;
- }
- *--ptr = '\0';
- return Py_BuildValue("s", buf);
- }
- else {
- Py_INCREF(Py_None);
- return Py_None;
- }
-}
-
-
-/*
- * Return NICs information a-la ifconfig as a list of tuples.
- * TODO: on Solaris we won't get any MAC address.
- */
-static PyObject*
-psutil_net_if_addrs(PyObject* self, PyObject* args)
-{
- struct ifaddrs *ifaddr, *ifa;
- int family;
-
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
- PyObject *py_address = NULL;
- PyObject *py_netmask = NULL;
- PyObject *py_broadcast = NULL;
-
- if (py_retlist == NULL)
- return NULL;
- if (getifaddrs(&ifaddr) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
- if (!ifa->ifa_addr)
- continue;
- family = ifa->ifa_addr->sa_family;
- py_address = psutil_convert_ipaddr(ifa->ifa_addr, family);
- // If the primary address can't be determined just skip it.
- // I've never seen this happen on Linux but I did on FreeBSD.
- if (py_address == Py_None)
- continue;
- if (py_address == NULL)
- goto error;
- py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family);
- if (py_netmask == NULL)
- goto error;
-#ifdef __linux
- py_broadcast = psutil_convert_ipaddr(ifa->ifa_ifu.ifu_broadaddr, family);
-#else
- py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
-#endif
- if (py_broadcast == NULL)
- goto error;
- py_tuple = Py_BuildValue(
- "(siOOO)",
- ifa->ifa_name,
- family,
- py_address,
- py_netmask,
- py_broadcast
- );
-
- if (! py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- Py_DECREF(py_address);
- Py_DECREF(py_netmask);
- Py_DECREF(py_broadcast);
- }
-
- freeifaddrs(ifaddr);
- return py_retlist;
-
-error:
- if (ifaddr != NULL)
- freeifaddrs(ifaddr);
- Py_DECREF(py_retlist);
- Py_XDECREF(py_tuple);
- Py_XDECREF(py_address);
- Py_XDECREF(py_netmask);
- Py_XDECREF(py_broadcast);
- return NULL;
-}
-
-
-/*
- * net_if_stats() implementation. This is here because it is common
- * to both OSX and FreeBSD and I didn't know where else to put it.
- */
-#if defined(__FreeBSD__) || defined(__APPLE__)
-
-#include <sys/sockio.h>
-#include <net/if_media.h>
-#include <net/if.h>
-
-int psutil_get_nic_speed(int ifm_active) {
- // Determine NIC speed. Taken from:
- // http://www.i-scream.org/libstatgrab/
- // Assuming only ETHER devices
- switch(IFM_TYPE(ifm_active)) {
- case IFM_ETHER:
- switch(IFM_SUBTYPE(ifm_active)) {
-#if defined(IFM_HPNA_1) && ((!defined(IFM_10G_LR)) \
- || (IFM_10G_LR != IFM_HPNA_1))
- // HomePNA 1.0 (1Mb/s)
- case(IFM_HPNA_1):
- return 1;
-#endif
- // 10 Mbit
- case(IFM_10_T): // 10BaseT - RJ45
- case(IFM_10_2): // 10Base2 - Thinnet
- case(IFM_10_5): // 10Base5 - AUI
- case(IFM_10_STP): // 10BaseT over shielded TP
- case(IFM_10_FL): // 10baseFL - Fiber
- return 10;
- // 100 Mbit
- case(IFM_100_TX): // 100BaseTX - RJ45
- case(IFM_100_FX): // 100BaseFX - Fiber
- case(IFM_100_T4): // 100BaseT4 - 4 pair cat 3
- case(IFM_100_VG): // 100VG-AnyLAN
- case(IFM_100_T2): // 100BaseT2
- return 100;
- // 1000 Mbit
- case(IFM_1000_SX): // 1000BaseSX - multi-mode fiber
- case(IFM_1000_LX): // 1000baseLX - single-mode fiber
- case(IFM_1000_CX): // 1000baseCX - 150ohm STP
-#if defined(IFM_1000_TX) && !defined(OPENBSD)
- // FreeBSD 4 and others (but NOT OpenBSD)?
- case(IFM_1000_TX):
-#endif
-#ifdef IFM_1000_FX
- case(IFM_1000_FX):
-#endif
-#ifdef IFM_1000_T
- case(IFM_1000_T):
-#endif
- return 1000;
-#if defined(IFM_10G_SR) || defined(IFM_10G_LR) || defined(IFM_10G_CX4) \
- || defined(IFM_10G_T)
-#ifdef IFM_10G_SR
- case(IFM_10G_SR):
-#endif
-#ifdef IFM_10G_LR
- case(IFM_10G_LR):
-#endif
-#ifdef IFM_10G_CX4
- case(IFM_10G_CX4):
-#endif
-#ifdef IFM_10G_TWINAX
- case(IFM_10G_TWINAX):
-#endif
-#ifdef IFM_10G_TWINAX_LONG
- case(IFM_10G_TWINAX_LONG):
-#endif
-#ifdef IFM_10G_T
- case(IFM_10G_T):
-#endif
- return 10000;
-#endif
-#if defined(IFM_2500_SX)
-#ifdef IFM_2500_SX
- case(IFM_2500_SX):
-#endif
- return 2500;
-#endif // any 2.5GBit stuff...
- // We don't know what it is
- default:
- return 0;
- }
- break;
-
-#ifdef IFM_TOKEN
- case IFM_TOKEN:
- switch(IFM_SUBTYPE(ifm_active)) {
- case IFM_TOK_STP4: // Shielded twisted pair 4m - DB9
- case IFM_TOK_UTP4: // Unshielded twisted pair 4m - RJ45
- return 4;
- case IFM_TOK_STP16: // Shielded twisted pair 16m - DB9
- case IFM_TOK_UTP16: // Unshielded twisted pair 16m - RJ45
- return 16;
-#if defined(IFM_TOK_STP100) || defined(IFM_TOK_UTP100)
-#ifdef IFM_TOK_STP100
- case IFM_TOK_STP100: // Shielded twisted pair 100m - DB9
-#endif
-#ifdef IFM_TOK_UTP100
- case IFM_TOK_UTP100: // Unshielded twisted pair 100m - RJ45
-#endif
- return 100;
-#endif
- // We don't know what it is
- default:
- return 0;
- }
- break;
-#endif
-
-#ifdef IFM_FDDI
- case IFM_FDDI:
- switch(IFM_SUBTYPE(ifm_active)) {
- // We don't know what it is
- default:
- return 0;
- }
- break;
-#endif
- case IFM_IEEE80211:
- switch(IFM_SUBTYPE(ifm_active)) {
- case IFM_IEEE80211_FH1: // Frequency Hopping 1Mbps
- case IFM_IEEE80211_DS1: // Direct Sequence 1Mbps
- return 1;
- case IFM_IEEE80211_FH2: // Frequency Hopping 2Mbps
- case IFM_IEEE80211_DS2: // Direct Sequence 2Mbps
- return 2;
- case IFM_IEEE80211_DS5: // Direct Sequence 5Mbps
- return 5;
- case IFM_IEEE80211_DS11: // Direct Sequence 11Mbps
- return 11;
- case IFM_IEEE80211_DS22: // Direct Sequence 22Mbps
- return 22;
- // We don't know what it is
- default:
- return 0;
- }
- break;
-
- default:
- return 0;
- }
-}
-
-
-/*
- * Return stats about a particular network interface.
- * References:
- * http://www.i-scream.org/libstatgrab/
- */
-static PyObject *
-psutil_net_if_stats(PyObject *self, PyObject *args)
-{
- char *nic_name;
- int sock = 0;
- int ret;
- int duplex;
- int speed;
- int mtu;
- struct ifreq ifr;
- struct ifmediareq ifmed;
-
- PyObject *py_is_up = NULL;
-
- if (! PyArg_ParseTuple(args, "s", &nic_name))
- return NULL;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock == -1)
- goto error;
- strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
-
- // is up?
- ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
- if (ret == -1)
- goto error;
- if ((ifr.ifr_flags & IFF_UP) != 0)
- py_is_up = Py_True;
- else
- py_is_up = Py_False;
- Py_INCREF(py_is_up);
-
- // MTU
- ret = ioctl(sock, SIOCGIFMTU, &ifr);
- if (ret == -1)
- goto error;
- mtu = ifr.ifr_mtu;
-
- // speed / duplex
- memset(&ifmed, 0, sizeof(struct ifmediareq));
- strlcpy(ifmed.ifm_name, nic_name, sizeof(ifmed.ifm_name));
- ret = ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmed);
- if (ret == -1) {
- speed = 0;
- duplex = 0;
- }
- else {
- speed = psutil_get_nic_speed(ifmed.ifm_active);
- if ((ifmed.ifm_active | IFM_FDX) == ifmed.ifm_active)
- duplex = 2;
- else if ((ifmed.ifm_active | IFM_HDX) == ifmed.ifm_active)
- duplex = 1;
- else
- duplex = 0;
- }
-
- close(sock);
- Py_DECREF(py_is_up);
-
- return Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu);
-
-error:
- Py_XDECREF(py_is_up);
- if (sock != 0)
- close(sock);
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
-}
-#endif // net_if_stats() implementation
-
-
-/*
- * define the psutil C module methods and initialize the module.
- */
-static PyMethodDef
-PsutilMethods[] =
-{
- {"getpriority", psutil_posix_getpriority, METH_VARARGS,
- "Return process priority"},
- {"setpriority", psutil_posix_setpriority, METH_VARARGS,
- "Set process priority"},
- {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
- "Retrieve NICs information"},
-#if defined(__FreeBSD__) || defined(__APPLE__)
- {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
- "Return NIC stats."},
-#endif
- {NULL, NULL, 0, NULL}
-};
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int
-psutil_posix_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int
-psutil_posix_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_posix",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_posix_traverse,
- psutil_posix_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_posix(void)
-
-#else
-#define INITERROR return
-
-void init_psutil_posix(void)
-#endif
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods);
-#endif
-
-#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__sun)
- PyModule_AddIntConstant(module, "AF_LINK", AF_LINK);
-#endif
-
- if (module == NULL)
- INITERROR;
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_posix.h b/python/psutil/psutil/_psutil_posix.h
deleted file mode 100644
index bbe6fc5ad..000000000
--- a/python/psutil/psutil/_psutil_posix.h
+++ /dev/null
@@ -1,15 +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>
-
-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
diff --git a/python/psutil/psutil/_psutil_sunos.c b/python/psutil/psutil/_psutil_sunos.c
deleted file mode 100644
index 0cb6978f2..000000000
--- a/python/psutil/psutil/_psutil_sunos.c
+++ /dev/null
@@ -1,1389 +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.
- *
- * Functions specific to Sun OS Solaris platforms.
- *
- * Thanks to Justin Venus who originally wrote a consistent part of
- * this in Cython which I later on translated in C.
- */
-
-
-#include <Python.h>
-
-// fix for "Cannot use procfs in the large file compilation environment"
-// error, see:
-// http://sourceware.org/ml/gdb-patches/2010-11/msg00336.html
-#undef _FILE_OFFSET_BITS
-#define _STRUCTURED_PROC 1
-
-// fix compilation issue on SunOS 5.10, see:
-// https://github.com/giampaolo/psutil/issues/421
-#define NEW_MIB_COMPLIANT
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/proc.h>
-#include <sys/swap.h>
-#include <sys/sysinfo.h>
-#include <sys/mntent.h> // for MNTTAB
-#include <sys/mnttab.h>
-#include <sys/procfs.h>
-#include <sys/sockio.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <utmpx.h>
-#include <kstat.h>
-#include <sys/ioctl.h>
-#include <sys/tihdr.h>
-#include <stropts.h>
-#include <inet/tcp.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-
-#include "_psutil_sunos.h"
-
-
-#define TV2DOUBLE(t) (((t).tv_nsec * 0.000000001) + (t).tv_sec)
-
-/*
- * Read a file content and fills a C structure with it.
- */
-int
-psutil_file_to_struct(char *path, void *fstruct, size_t size)
-{
- int fd;
- size_t nbytes;
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
- return 0;
- }
- nbytes = read(fd, fstruct, size);
- if (nbytes <= 0) {
- close(fd);
- PyErr_SetFromErrno(PyExc_OSError);
- return 0;
- }
- if (nbytes != size) {
- close(fd);
- PyErr_SetString(PyExc_RuntimeError, "structure size mismatch");
- return 0;
- }
- close(fd);
- return nbytes;
-}
-
-
-/*
- * Return process ppid, rss, vms, ctime, nice, nthreads, status and tty
- * as a Python tuple.
- */
-static PyObject *
-psutil_proc_basic_info(PyObject *self, PyObject *args)
-{
- int pid;
- char path[100];
- psinfo_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/psinfo", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- return Py_BuildValue("ikkdiiik",
- info.pr_ppid, // parent pid
- info.pr_rssize, // rss
- info.pr_size, // vms
- TV2DOUBLE(info.pr_start), // create time
- info.pr_lwp.pr_nice, // nice
- info.pr_nlwp, // no. of threads
- info.pr_lwp.pr_state, // status code
- info.pr_ttydev // tty nr
- );
-}
-
-
-/*
- * Return process name and args as a Python tuple.
- */
-static PyObject *
-psutil_proc_name_and_args(PyObject *self, PyObject *args)
-{
- int pid;
- char path[100];
- psinfo_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/psinfo", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- return Py_BuildValue("ss", info.pr_fname, info.pr_psargs);
-}
-
-
-/*
- * Return process user and system CPU times as a Python tuple.
- */
-static PyObject *
-psutil_proc_cpu_times(PyObject *self, PyObject *args)
-{
- int pid;
- char path[100];
- pstatus_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/status", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- // results are more precise than os.times()
- return Py_BuildValue("dd",
- TV2DOUBLE(info.pr_utime),
- TV2DOUBLE(info.pr_stime));
-}
-
-
-/*
- * Return process uids/gids as a Python tuple.
- */
-static PyObject *
-psutil_proc_cred(PyObject *self, PyObject *args)
-{
- int pid;
- char path[100];
- prcred_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/cred", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- return Py_BuildValue("iiiiii",
- info.pr_ruid, info.pr_euid, info.pr_suid,
- info.pr_rgid, info.pr_egid, info.pr_sgid);
-}
-
-
-/*
- * Return process uids/gids as a Python tuple.
- */
-static PyObject *
-psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
-{
- int pid;
- char path[100];
- prusage_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/usage", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- return Py_BuildValue("kk", info.pr_vctx, info.pr_ictx);
-}
-
-
-/*
- * Process IO counters.
- *
- * Commented out and left here as a reminder. Apparently we cannot
- * retrieve process IO stats because:
- * - 'pr_ioch' is a sum of chars read and written, with no distinction
- * - 'pr_inblk' and 'pr_oublk', which should be the number of bytes
- * read and written, hardly increase and according to:
- * http://www.brendangregg.com/Perf/paper_diskubyp1.pdf
- * ...they should be meaningless anyway.
- *
-static PyObject*
-proc_io_counters(PyObject* self, PyObject* args)
-{
- int pid;
- char path[100];
- prusage_t info;
-
- if (! PyArg_ParseTuple(args, "i", &pid))
- return NULL;
- sprintf(path, "/proc/%i/usage", pid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
-
- // On Solaris we only have 'pr_ioch' which accounts for bytes read
- // *and* written.
- // 'pr_inblk' and 'pr_oublk' should be expressed in blocks of
- // 8KB according to:
- // http://www.brendangregg.com/Perf/paper_diskubyp1.pdf (pag. 8)
- return Py_BuildValue("kkkk",
- info.pr_ioch,
- info.pr_ioch,
- info.pr_inblk,
- info.pr_oublk);
-}
- */
-
-
-/*
- * Return information about a given process thread.
- */
-static PyObject *
-psutil_proc_query_thread(PyObject *self, PyObject *args)
-{
- int pid, tid;
- char path[100];
- lwpstatus_t info;
-
- if (! PyArg_ParseTuple(args, "ii", &pid, &tid))
- return NULL;
- sprintf(path, "/proc/%i/lwp/%i/lwpstatus", pid, tid);
- if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
- return NULL;
- return Py_BuildValue("dd",
- TV2DOUBLE(info.pr_utime),
- TV2DOUBLE(info.pr_stime));
-}
-
-
-/*
- * Return information about system virtual memory.
- */
-static PyObject *
-psutil_swap_mem(PyObject *self, PyObject *args)
-{
-// XXX (arghhh!)
-// total/free swap mem: commented out as for some reason I can't
-// manage to get the same results shown by "swap -l", despite the
-// code below is exactly the same as:
-// http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/
-// cmd/swap/swap.c
-// We're going to parse "swap -l" output from Python (sigh!)
-
-/*
- struct swaptable *st;
- struct swapent *swapent;
- int i;
- struct stat64 statbuf;
- char *path;
- char fullpath[MAXPATHLEN+1];
- int num;
-
- if ((num = swapctl(SC_GETNSWP, NULL)) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
- if (num == 0) {
- PyErr_SetString(PyExc_RuntimeError, "no swap devices configured");
- return NULL;
- }
- if ((st = malloc(num * sizeof(swapent_t) + sizeof (int))) == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "malloc failed");
- return NULL;
- }
- if ((path = malloc(num * MAXPATHLEN)) == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "malloc failed");
- return NULL;
- }
- swapent = st->swt_ent;
- for (i = 0; i < num; i++, swapent++) {
- swapent->ste_path = path;
- path += MAXPATHLEN;
- }
- st->swt_n = num;
- if ((num = swapctl(SC_LIST, st)) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
-
- swapent = st->swt_ent;
- long t = 0, f = 0;
- for (i = 0; i < num; i++, swapent++) {
- int diskblks_per_page =(int)(sysconf(_SC_PAGESIZE) >> DEV_BSHIFT);
- t += (long)swapent->ste_pages;
- f += (long)swapent->ste_free;
- }
-
- free(st);
- return Py_BuildValue("(kk)", t, f);
-*/
-
- kstat_ctl_t *kc;
- kstat_t *k;
- cpu_stat_t *cpu;
- int cpu_count = 0;
- int flag = 0;
- uint_t sin = 0;
- uint_t sout = 0;
-
- kc = kstat_open();
- if (kc == NULL)
- return PyErr_SetFromErrno(PyExc_OSError);;
-
- k = kc->kc_chain;
- while (k != NULL) {
- if ((strncmp(k->ks_name, "cpu_stat", 8) == 0) && \
- (kstat_read(kc, k, NULL) != -1) )
- {
- flag = 1;
- cpu = (cpu_stat_t *) k->ks_data;
- sin += cpu->cpu_vminfo.pgswapin; // num pages swapped in
- sout += cpu->cpu_vminfo.pgswapout; // num pages swapped out
- }
- cpu_count += 1;
- k = k->ks_next;
- }
- kstat_close(kc);
- if (!flag) {
- PyErr_SetString(PyExc_RuntimeError, "no swap device was found");
- return NULL;
- }
- return Py_BuildValue("(II)", sin, sout);
-}
-
-
-/*
- * Return users currently connected on the system.
- */
-static PyObject *
-psutil_users(PyObject *self, PyObject *args)
-{
- struct utmpx *ut;
- PyObject *ret_list = PyList_New(0);
- PyObject *tuple = NULL;
- PyObject *user_proc = NULL;
-
- if (ret_list == NULL)
- return NULL;
-
- while (NULL != (ut = getutxent())) {
- if (ut->ut_type == USER_PROCESS)
- user_proc = Py_True;
- else
- user_proc = Py_False;
- tuple = Py_BuildValue(
- "(sssfO)",
- ut->ut_user, // username
- ut->ut_line, // tty
- ut->ut_host, // hostname
- (float)ut->ut_tv.tv_sec, // tstamp
- user_proc); // (bool) user process
- if (tuple == NULL)
- goto error;
- if (PyList_Append(ret_list, tuple))
- goto error;
- Py_DECREF(tuple);
- }
- endutent();
-
- return ret_list;
-
-error:
- Py_XDECREF(tuple);
- Py_DECREF(ret_list);
- if (ut != NULL)
- endutent();
- return NULL;
-}
-
-
-/*
- * Return disk mounted partitions as a list of tuples including device,
- * mount point and filesystem type.
- */
-static PyObject *
-psutil_disk_partitions(PyObject *self, PyObject *args)
-{
- FILE *file;
- struct mnttab mt;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- file = fopen(MNTTAB, "rb");
- if (file == NULL) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- while (getmntent(file, &mt) == 0) {
- py_tuple = Py_BuildValue(
- "(ssss)",
- mt.mnt_special, // device
- mt.mnt_mountp, // mount point
- mt.mnt_fstype, // fs type
- mt.mnt_mntopts); // options
- if (py_tuple == NULL)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
-
- }
- fclose(file);
- return py_retlist;
-
-error:
- Py_XDECREF(py_tuple);
- Py_DECREF(py_retlist);
- if (file != NULL)
- fclose(file);
- return NULL;
-}
-
-
-/*
- * Return system-wide CPU times.
- */
-static PyObject *
-psutil_per_cpu_times(PyObject *self, PyObject *args)
-{
- kstat_ctl_t *kc;
- kstat_t *ksp;
- cpu_stat_t cs;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_cputime = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- kc = kstat_open();
- if (kc == NULL) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
- if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
- if (kstat_read(kc, ksp, &cs) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- py_cputime = Py_BuildValue("ffff",
- (float)cs.cpu_sysinfo.cpu[CPU_USER],
- (float)cs.cpu_sysinfo.cpu[CPU_KERNEL],
- (float)cs.cpu_sysinfo.cpu[CPU_IDLE],
- (float)cs.cpu_sysinfo.cpu[CPU_WAIT]);
- if (py_cputime == NULL)
- goto error;
- if (PyList_Append(py_retlist, py_cputime))
- goto error;
- Py_DECREF(py_cputime);
- py_cputime = NULL;
- }
- }
-
- kstat_close(kc);
- return py_retlist;
-
-error:
- Py_XDECREF(py_cputime);
- Py_DECREF(py_retlist);
- if (kc != NULL)
- kstat_close(kc);
- return NULL;
-}
-
-
-/*
- * Return disk IO statistics.
- */
-static PyObject *
-psutil_disk_io_counters(PyObject *self, PyObject *args)
-{
- kstat_ctl_t *kc;
- kstat_t *ksp;
- kstat_io_t kio;
- PyObject *py_retdict = PyDict_New();
- PyObject *py_disk_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- kc = kstat_open();
- if (kc == NULL) {
- PyErr_SetFromErrno(PyExc_OSError);;
- goto error;
- }
- ksp = kc->kc_chain;
- while (ksp != NULL) {
- if (ksp->ks_type == KSTAT_TYPE_IO) {
- if (strcmp(ksp->ks_class, "disk") == 0) {
- if (kstat_read(kc, ksp, &kio) == -1) {
- kstat_close(kc);
- return PyErr_SetFromErrno(PyExc_OSError);;
- }
- py_disk_info = Py_BuildValue(
- "(IIKKLL)",
- kio.reads,
- kio.writes,
- kio.nread,
- kio.nwritten,
- kio.rtime / 1000 / 1000, // from nano to milli secs
- kio.wtime / 1000 / 1000 // from nano to milli secs
- );
- if (!py_disk_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, ksp->ks_name,
- py_disk_info))
- goto error;
- Py_DECREF(py_disk_info);
- }
- }
- ksp = ksp->ks_next;
- }
- kstat_close(kc);
-
- return py_retdict;
-
-error:
- Py_XDECREF(py_disk_info);
- Py_DECREF(py_retdict);
- if (kc != NULL)
- kstat_close(kc);
- return NULL;
-}
-
-
-/*
- * Return process memory mappings.
- */
-static PyObject *
-psutil_proc_memory_maps(PyObject *self, PyObject *args)
-{
- int pid;
- int fd = -1;
- char path[100];
- char perms[10];
- char *name;
- struct stat st;
- pstatus_t status;
-
- prxmap_t *xmap = NULL, *p;
- off_t size;
- size_t nread;
- int nmap;
- uintptr_t pr_addr_sz;
- uintptr_t stk_base_sz, brk_base_sz;
-
- PyObject *pytuple = NULL;
- PyObject *py_retlist = PyList_New(0);
-
- if (py_retlist == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "i", &pid))
- goto error;
-
- sprintf(path, "/proc/%i/status", pid);
- if (! psutil_file_to_struct(path, (void *)&status, sizeof(status)))
- goto error;
-
- sprintf(path, "/proc/%i/xmap", pid);
- if (stat(path, &st) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- size = st.st_size;
-
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- xmap = (prxmap_t *)malloc(size);
- if (xmap == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- nread = pread(fd, xmap, size, 0);
- nmap = nread / sizeof(prxmap_t);
- p = xmap;
-
- while (nmap) {
- nmap -= 1;
- if (p == NULL) {
- p += 1;
- continue;
- }
-
- perms[0] = '\0';
- pr_addr_sz = p->pr_vaddr + p->pr_size;
-
- // perms
- sprintf(perms, "%c%c%c%c%c%c", p->pr_mflags & MA_READ ? 'r' : '-',
- p->pr_mflags & MA_WRITE ? 'w' : '-',
- p->pr_mflags & MA_EXEC ? 'x' : '-',
- p->pr_mflags & MA_SHARED ? 's' : '-',
- p->pr_mflags & MA_NORESERVE ? 'R' : '-',
- p->pr_mflags & MA_RESERVED1 ? '*' : ' ');
-
- // name
- if (strlen(p->pr_mapname) > 0) {
- name = p->pr_mapname;
- }
- else {
- if ((p->pr_mflags & MA_ISM) || (p->pr_mflags & MA_SHM)) {
- name = "[shmid]";
- }
- else {
- stk_base_sz = status.pr_stkbase + status.pr_stksize;
- brk_base_sz = status.pr_brkbase + status.pr_brksize;
-
- if ((pr_addr_sz > status.pr_stkbase) &&
- (p->pr_vaddr < stk_base_sz)) {
- name = "[stack]";
- }
- else if ((p->pr_mflags & MA_ANON) && \
- (pr_addr_sz > status.pr_brkbase) && \
- (p->pr_vaddr < brk_base_sz)) {
- name = "[heap]";
- }
- else {
- name = "[anon]";
- }
- }
- }
-
- pytuple = Py_BuildValue("iisslll",
- p->pr_vaddr,
- pr_addr_sz,
- perms,
- name,
- (long)p->pr_rss * p->pr_pagesize,
- (long)p->pr_anon * p->pr_pagesize,
- (long)p->pr_locked * p->pr_pagesize);
- if (!pytuple)
- goto error;
- if (PyList_Append(py_retlist, pytuple))
- goto error;
- Py_DECREF(pytuple);
-
- // increment pointer
- p += 1;
- }
-
- close(fd);
- free(xmap);
- return py_retlist;
-
-error:
- if (fd != -1)
- close(fd);
- Py_XDECREF(pytuple);
- Py_DECREF(py_retlist);
- if (xmap != NULL)
- free(xmap);
- return NULL;
-}
-
-
-/*
- * Return a list of tuples for network I/O statistics.
- */
-static PyObject *
-psutil_net_io_counters(PyObject *self, PyObject *args)
-{
- kstat_ctl_t *kc = NULL;
- kstat_t *ksp;
- kstat_named_t *rbytes, *wbytes, *rpkts, *wpkts, *ierrs, *oerrs;
-
- PyObject *py_retdict = PyDict_New();
- PyObject *py_ifc_info = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- kc = kstat_open();
- if (kc == NULL)
- goto error;
-
- ksp = kc->kc_chain;
- while (ksp != NULL) {
- if (ksp->ks_type != KSTAT_TYPE_NAMED)
- goto next;
- if (strcmp(ksp->ks_class, "net") != 0)
- goto next;
- /*
- // XXX "lo" (localhost) interface makes kstat_data_lookup() fail
- // (maybe because "ifconfig -a" says it's a virtual interface?).
- if ((strcmp(ksp->ks_module, "link") != 0) &&
- (strcmp(ksp->ks_module, "lo") != 0)) {
- goto skip;
- */
- if ((strcmp(ksp->ks_module, "link") != 0))
- goto next;
-
- if (kstat_read(kc, ksp, NULL) == -1) {
- errno = 0;
- continue;
- }
-
- rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes");
- wbytes = (kstat_named_t *)kstat_data_lookup(ksp, "obytes");
- rpkts = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets");
- wpkts = (kstat_named_t *)kstat_data_lookup(ksp, "opackets");
- ierrs = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors");
- oerrs = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors");
-
- if ((rbytes == NULL) || (wbytes == NULL) || (rpkts == NULL) ||
- (wpkts == NULL) || (ierrs == NULL) || (oerrs == NULL))
- {
- PyErr_SetString(PyExc_RuntimeError, "kstat_data_lookup() failed");
- goto error;
- }
-
-#if defined(_INT64_TYPE)
- py_ifc_info = Py_BuildValue("(KKKKkkii)",
- wbytes->value.ui64,
- rbytes->value.ui64,
- wpkts->value.ui64,
- rpkts->value.ui64,
- ierrs->value.ui32,
- oerrs->value.ui32,
-#else
- py_ifc_info = Py_BuildValue("(kkkkkkii)",
- wbytes->value.ui32,
- rbytes->value.ui32,
- wpkts->value.ui32,
- rpkts->value.ui32,
- ierrs->value.ui32,
- oerrs->value.ui32,
-#endif
- 0, // dropin not supported
- 0 // dropout not supported
- );
- if (!py_ifc_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info))
- goto error;
- Py_DECREF(py_ifc_info);
- goto next;
-
-next:
- ksp = ksp->ks_next;
- }
-
- kstat_close(kc);
- return py_retdict;
-
-error:
- Py_XDECREF(py_ifc_info);
- Py_DECREF(py_retdict);
- if (kc != NULL)
- kstat_close(kc);
- return NULL;
-}
-
-
-#ifndef EXPER_IP_AND_ALL_IRES
-#define EXPER_IP_AND_ALL_IRES (1024+4)
-#endif
-
-// a signaler for connections without an actual status
-static int PSUTIL_CONN_NONE = 128;
-
-/*
- * Return TCP and UDP connections opened by process.
- * UNIX sockets are excluded.
- *
- * Thanks to:
- * https://github.com/DavidGriffith/finx/blob/master/
- * nxsensor-3.5.0-1/src/sysdeps/solaris.c
- * ...and:
- * https://hg.java.net/hg/solaris~on-src/file/tip/usr/src/cmd/
- * cmd-inet/usr.bin/netstat/netstat.c
- */
-static PyObject *
-psutil_net_connections(PyObject *self, PyObject *args)
-{
- long pid;
- int sd = 0;
- mib2_tcpConnEntry_t *tp = NULL;
- mib2_udpEntry_t *ude;
-#if defined(AF_INET6)
- mib2_tcp6ConnEntry_t *tp6;
- mib2_udp6Entry_t *ude6;
-#endif
- char buf[512];
- int i, flags, getcode, num_ent, state;
- char lip[200], rip[200];
- int lport, rport;
- int processed_pid;
- int databuf_init = 0;
- struct strbuf ctlbuf, databuf;
- struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf;
- struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf;
- struct T_error_ack *tea = (struct T_error_ack *)buf;
- struct opthdr *mibhdr;
-
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
- PyObject *py_laddr = NULL;
- PyObject *py_raddr = NULL;
- PyObject *af_filter = NULL;
- PyObject *type_filter = NULL;
-
- if (py_retlist == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
- goto error;
- if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
- PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
- goto error;
- }
-
- sd = open("/dev/arp", O_RDWR);
- if (sd == -1) {
- PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/dev/arp");
- goto error;
- }
-
- /*
- XXX - These 2 are used in ifconfig.c but they seem unnecessary
- ret = ioctl(sd, I_PUSH, "tcp");
- if (ret == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- ret = ioctl(sd, I_PUSH, "udp");
- if (ret == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- */
-
- // OK, this mess is basically copied and pasted from nxsensor project
- // which copied and pasted it from netstat source code, mibget()
- // function. Also see:
- // http://stackoverflow.com/questions/8723598/
- tor->PRIM_type = T_SVR4_OPTMGMT_REQ;
- tor->OPT_offset = sizeof (struct T_optmgmt_req);
- tor->OPT_length = sizeof (struct opthdr);
- tor->MGMT_flags = T_CURRENT;
- mibhdr = (struct opthdr *)&tor[1];
- mibhdr->level = EXPER_IP_AND_ALL_IRES;
- mibhdr->name = 0;
- mibhdr->len = 0;
-
- ctlbuf.buf = buf;
- ctlbuf.len = tor->OPT_offset + tor->OPT_length;
- flags = 0; // request to be sent in non-priority
-
- if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- mibhdr = (struct opthdr *)&toa[1];
- ctlbuf.maxlen = sizeof (buf);
-
- for (;;) {
- flags = 0;
- getcode = getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags);
-
- if (getcode != MOREDATA ||
- ctlbuf.len < sizeof (struct T_optmgmt_ack) ||
- toa->PRIM_type != T_OPTMGMT_ACK ||
- toa->MGMT_flags != T_SUCCESS)
- {
- break;
- }
- if (ctlbuf.len >= sizeof (struct T_error_ack) &&
- tea->PRIM_type == T_ERROR_ACK)
- {
- PyErr_SetString(PyExc_RuntimeError, "ERROR_ACK");
- goto error;
- }
- if (getcode == 0 &&
- ctlbuf.len >= sizeof (struct T_optmgmt_ack) &&
- toa->PRIM_type == T_OPTMGMT_ACK &&
- toa->MGMT_flags == T_SUCCESS)
- {
- PyErr_SetString(PyExc_RuntimeError, "ERROR_T_OPTMGMT_ACK");
- goto error;
- }
-
- databuf.maxlen = mibhdr->len;
- databuf.len = 0;
- databuf.buf = (char *)malloc((int)mibhdr->len);
- if (!databuf.buf) {
- PyErr_NoMemory();
- goto error;
- }
- databuf_init = 1;
-
- flags = 0;
- getcode = getmsg(sd, (struct strbuf *)0, &databuf, &flags);
- if (getcode < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
- // TCPv4
- if (mibhdr->level == MIB2_TCP && mibhdr->name == MIB2_TCP_13) {
- tp = (mib2_tcpConnEntry_t *)databuf.buf;
- num_ent = mibhdr->len / sizeof(mib2_tcpConnEntry_t);
- for (i = 0; i < num_ent; i++, tp++) {
- processed_pid = tp->tcpConnCreationProcess;
- if (pid != -1 && processed_pid != pid)
- continue;
- // construct local/remote addresses
- inet_ntop(AF_INET, &tp->tcpConnLocalAddress, lip, sizeof(lip));
- inet_ntop(AF_INET, &tp->tcpConnRemAddress, rip, sizeof(rip));
- lport = tp->tcpConnLocalPort;
- rport = tp->tcpConnRemPort;
-
- // contruct python tuple/list
- py_laddr = Py_BuildValue("(si)", lip, lport);
- if (!py_laddr)
- goto error;
- if (rport != 0)
- py_raddr = Py_BuildValue("(si)", rip, rport);
- else {
- py_raddr = Py_BuildValue("()");
- }
- if (!py_raddr)
- goto error;
- state = tp->tcpConnEntryInfo.ce_state;
-
- // add item
- py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_STREAM,
- py_laddr, py_raddr, state,
- processed_pid);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- }
-#if defined(AF_INET6)
- // TCPv6
- else if (mibhdr->level == MIB2_TCP6 && mibhdr->name == MIB2_TCP6_CONN)
- {
- tp6 = (mib2_tcp6ConnEntry_t *)databuf.buf;
- num_ent = mibhdr->len / sizeof(mib2_tcp6ConnEntry_t);
-
- for (i = 0; i < num_ent; i++, tp6++) {
- processed_pid = tp6->tcp6ConnCreationProcess;
- if (pid != -1 && processed_pid != pid)
- continue;
- // construct local/remote addresses
- inet_ntop(AF_INET6, &tp6->tcp6ConnLocalAddress, lip, sizeof(lip));
- inet_ntop(AF_INET6, &tp6->tcp6ConnRemAddress, rip, sizeof(rip));
- lport = tp6->tcp6ConnLocalPort;
- rport = tp6->tcp6ConnRemPort;
-
- // contruct python tuple/list
- py_laddr = Py_BuildValue("(si)", lip, lport);
- if (!py_laddr)
- goto error;
- if (rport != 0)
- py_raddr = Py_BuildValue("(si)", rip, rport);
- else
- py_raddr = Py_BuildValue("()");
- if (!py_raddr)
- goto error;
- state = tp6->tcp6ConnEntryInfo.ce_state;
-
- // add item
- py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, SOCK_STREAM,
- py_laddr, py_raddr, state, processed_pid);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- }
-#endif
- // UDPv4
- else if (mibhdr->level == MIB2_UDP || mibhdr->level == MIB2_UDP_ENTRY) {
- ude = (mib2_udpEntry_t *)databuf.buf;
- num_ent = mibhdr->len / sizeof(mib2_udpEntry_t);
- for (i = 0; i < num_ent; i++, ude++) {
- processed_pid = ude->udpCreationProcess;
- if (pid != -1 && processed_pid != pid)
- continue;
- // XXX Very ugly hack! It seems we get here only the first
- // time we bump into a UDPv4 socket. PID is a very high
- // number (clearly impossible) and the address does not
- // belong to any valid interface. Not sure what else
- // to do other than skipping.
- if (processed_pid > 131072)
- continue;
- inet_ntop(AF_INET, &ude->udpLocalAddress, lip, sizeof(lip));
- lport = ude->udpLocalPort;
- py_laddr = Py_BuildValue("(si)", lip, lport);
- if (!py_laddr)
- goto error;
- py_raddr = Py_BuildValue("()");
- if (!py_raddr)
- goto error;
- py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_DGRAM,
- py_laddr, py_raddr, PSUTIL_CONN_NONE,
- processed_pid);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- }
-#if defined(AF_INET6)
- // UDPv6
- else if (mibhdr->level == MIB2_UDP6 ||
- mibhdr->level == MIB2_UDP6_ENTRY)
- {
- ude6 = (mib2_udp6Entry_t *)databuf.buf;
- num_ent = mibhdr->len / sizeof(mib2_udp6Entry_t);
- for (i = 0; i < num_ent; i++, ude6++) {
- processed_pid = ude6->udp6CreationProcess;
- if (pid != -1 && processed_pid != pid)
- continue;
- inet_ntop(AF_INET6, &ude6->udp6LocalAddress, lip, sizeof(lip));
- lport = ude6->udp6LocalPort;
- py_laddr = Py_BuildValue("(si)", lip, lport);
- if (!py_laddr)
- goto error;
- py_raddr = Py_BuildValue("()");
- if (!py_raddr)
- goto error;
- py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, SOCK_DGRAM,
- py_laddr, py_raddr, PSUTIL_CONN_NONE,
- processed_pid);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- }
-#endif
- free(databuf.buf);
- }
-
- close(sd);
- return py_retlist;
-
-error:
- Py_XDECREF(py_tuple);
- Py_XDECREF(py_laddr);
- Py_XDECREF(py_raddr);
- Py_DECREF(py_retlist);
- if (databuf_init == 1)
- free(databuf.buf);
- if (sd != 0)
- close(sd);
- return NULL;
-}
-
-
-static PyObject *
-psutil_boot_time(PyObject *self, PyObject *args)
-{
- float boot_time = 0.0;
- struct utmpx *ut;
-
- while (NULL != (ut = getutxent())) {
- if (ut->ut_type == BOOT_TIME) {
- boot_time = (float)ut->ut_tv.tv_sec;
- break;
- }
- }
- endutent();
- if (boot_time != 0.0) {
- return Py_BuildValue("f", boot_time);
- }
- else {
- PyErr_SetString(PyExc_RuntimeError, "can't determine boot time");
- return NULL;
- }
-}
-
-
-/*
- * Return the number of physical CPU cores on the system.
- */
-static PyObject *
-psutil_cpu_count_phys(PyObject *self, PyObject *args)
-{
- kstat_ctl_t *kc;
- kstat_t *ksp;
- int ncpus = 0;
-
- kc = kstat_open();
- if (kc == NULL)
- goto error;
- ksp = kstat_lookup(kc, "cpu_info", -1, NULL);
- if (ksp == NULL)
- goto error;
-
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- if (strcmp(ksp->ks_module, "cpu_info") != 0)
- continue;
- if (kstat_read(kc, ksp, NULL) == -1)
- goto error;
- ncpus += 1;
- }
-
- kstat_close(kc);
- if (ncpus > 0)
- return Py_BuildValue("i", ncpus);
- else
- goto error;
-
-error:
- // mimic os.cpu_count()
- if (kc != NULL)
- kstat_close(kc);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Return stats about a particular network
- * interface. References:
- * https://github.com/dpaleino/wicd/blob/master/wicd/backends/be-ioctl.py
- * http://www.i-scream.org/libstatgrab/
- */
-static PyObject*
-psutil_net_if_stats(PyObject* self, PyObject* args)
-{
- kstat_ctl_t *kc = NULL;
- kstat_t *ksp;
- kstat_named_t *knp;
- int ret;
- int sock = 0;
- int duplex;
- int speed;
-
- PyObject *py_retdict = PyDict_New();
- PyObject *py_ifc_info = NULL;
- PyObject *py_is_up = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- kc = kstat_open();
- if (kc == NULL)
- goto error;
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock == -1)
- goto error;
-
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- if (strcmp(ksp->ks_class, "net") == 0) {
- struct ifreq ifr;
-
- kstat_read(kc, ksp, NULL);
- if (ksp->ks_type != KSTAT_TYPE_NAMED)
- continue;
- if (strcmp(ksp->ks_class, "net") != 0)
- continue;
-
- strncpy(ifr.ifr_name, ksp->ks_name, sizeof(ifr.ifr_name));
- ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
- if (ret == -1)
- continue; // not a network interface
-
- // is up?
- if ((ifr.ifr_flags & IFF_UP) != 0) {
- if ((knp = kstat_data_lookup(ksp, "link_up")) != NULL) {
- if (knp->value.ui32 != 0u)
- py_is_up = Py_True;
- else
- py_is_up = Py_False;
- }
- else {
- py_is_up = Py_True;
- }
- }
- else {
- py_is_up = Py_False;
- }
- Py_INCREF(py_is_up);
-
- // duplex
- duplex = 0; // unknown
- if ((knp = kstat_data_lookup(ksp, "link_duplex")) != NULL) {
- if (knp->value.ui32 == 1)
- duplex = 1; // half
- else if (knp->value.ui32 == 2)
- duplex = 2; // full
- }
-
- // speed
- if ((knp = kstat_data_lookup(ksp, "ifspeed")) != NULL)
- // expressed in bits per sec, we want mega bits per sec
- speed = (int)knp->value.ui64 / 1000000;
- else
- speed = 0;
-
- // mtu
- ret = ioctl(sock, SIOCGIFMTU, &ifr);
- if (ret == -1)
- goto error;
-
- py_ifc_info = Py_BuildValue("(Oiii)", py_is_up, duplex, speed,
- ifr.ifr_mtu);
- if (!py_ifc_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info))
- goto error;
- Py_DECREF(py_ifc_info);
- }
- }
-
- close(sock);
- kstat_close(kc);
- return py_retdict;
-
-error:
- Py_XDECREF(py_is_up);
- Py_XDECREF(py_ifc_info);
- Py_DECREF(py_retdict);
- if (sock != 0)
- close(sock);
- if (kc != NULL)
- kstat_close(kc);
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
-}
-
-
-/*
- * define the psutil C module methods and initialize the module.
- */
-static PyMethodDef
-PsutilMethods[] =
-{
- // --- process-related functions
- {"proc_basic_info", psutil_proc_basic_info, METH_VARARGS,
- "Return process ppid, rss, vms, ctime, nice, nthreads, status and tty"},
- {"proc_name_and_args", psutil_proc_name_and_args, METH_VARARGS,
- "Return process name and args."},
- {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
- "Return process user and system CPU times."},
- {"proc_cred", psutil_proc_cred, METH_VARARGS,
- "Return process uids/gids."},
- {"query_process_thread", psutil_proc_query_thread, METH_VARARGS,
- "Return info about a process thread"},
- {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
- "Return process memory mappings"},
- {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
- "Return the number of context switches performed by process"},
-
- // --- system-related functions
- {"swap_mem", psutil_swap_mem, METH_VARARGS,
- "Return information about system swap memory."},
- {"users", psutil_users, METH_VARARGS,
- "Return currently connected users."},
- {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
- "Return disk partitions."},
- {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
- "Return system per-CPU times."},
- {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
- "Return a Python dict of tuples for disk I/O statistics."},
- {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
- "Return a Python dict of tuples for network I/O statistics."},
- {"boot_time", psutil_boot_time, METH_VARARGS,
- "Return system boot time in seconds since the EPOCH."},
- {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
- "Return the number of physical CPUs on the system."},
- {"net_connections", psutil_net_connections, METH_VARARGS,
- "Return TCP and UDP syste-wide open connections."},
- {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
- "Return NIC stats (isup, duplex, speed, mtu)"},
-
-{NULL, NULL, 0, NULL}
-};
-
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int
-psutil_sunos_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int
-psutil_sunos_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_sunos",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_sunos_traverse,
- psutil_sunos_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_sunos(void)
-
-#else
-#define INITERROR return
-
-void init_psutil_sunos(void)
-#endif
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_sunos", PsutilMethods);
-#endif
- PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
-
- PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
- PyModule_AddIntConstant(module, "SRUN", SRUN);
- PyModule_AddIntConstant(module, "SZOMB", SZOMB);
- PyModule_AddIntConstant(module, "SSTOP", SSTOP);
- PyModule_AddIntConstant(module, "SIDL", SIDL);
- PyModule_AddIntConstant(module, "SONPROC", SONPROC);
- PyModule_AddIntConstant(module, "SWAIT", SWAIT);
-
- PyModule_AddIntConstant(module, "PRNODEV", PRNODEV); // for process tty
-
- PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
- PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
- PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
- PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
- PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
- PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
- PyModule_AddIntConstant(module, "TCPS_SYN_RCVD", TCPS_SYN_RCVD);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
- PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
- PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
- PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
- // sunos specific
- PyModule_AddIntConstant(module, "TCPS_IDLE", TCPS_IDLE);
- // sunos specific
- PyModule_AddIntConstant(module, "TCPS_BOUND", TCPS_BOUND);
- PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
-
- if (module == NULL)
- INITERROR;
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_sunos.h b/python/psutil/psutil/_psutil_sunos.h
deleted file mode 100644
index f93dbfe0f..000000000
--- a/python/psutil/psutil/_psutil_sunos.h
+++ /dev/null
@@ -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);
diff --git a/python/psutil/psutil/_psutil_windows.c b/python/psutil/psutil/_psutil_windows.c
deleted file mode 100644
index 3e0f7a7cd..000000000
--- a/python/psutil/psutil/_psutil_windows.c
+++ /dev/null
@@ -1,3405 +0,0 @@
-/*
- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Windows platform-specific module methods for _psutil_windows
- */
-
-// Fixes clash between winsock2.h and windows.h
-#define WIN32_LEAN_AND_MEAN
-
-#include <Python.h>
-#include <windows.h>
-#include <Psapi.h>
-#include <time.h>
-#include <lm.h>
-#include <WinIoCtl.h>
-#include <tchar.h>
-#include <tlhelp32.h>
-#include <winsock2.h>
-#include <iphlpapi.h>
-#include <wtsapi32.h>
-#include <ws2tcpip.h>
-
-// Link with Iphlpapi.lib
-#pragma comment(lib, "IPHLPAPI.lib")
-
-#include "_psutil_windows.h"
-#include "_psutil_common.h"
-#include "arch/windows/security.h"
-#include "arch/windows/process_info.h"
-#include "arch/windows/process_handles.h"
-#include "arch/windows/ntextapi.h"
-#include "arch/windows/inet_ntop.h"
-
-#ifdef __MINGW32__
-#include "arch/windows/glpi.h"
-#endif
-
-
-/*
- * ============================================================================
- * Utilities
- * ============================================================================
- */
-
- // a flag for connections without an actual status
-static int PSUTIL_CONN_NONE = 128;
-
-#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
-#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
-#define LO_T ((float)1e-7)
-#define HI_T (LO_T*4294967296.0)
-#define BYTESWAP_USHORT(x) ((((USHORT)(x) << 8) | ((USHORT)(x) >> 8)) & 0xffff)
-#ifndef AF_INET6
-#define AF_INET6 23
-#endif
-#define _psutil_conn_decref_objs() \
- Py_DECREF(_AF_INET); \
- Py_DECREF(_AF_INET6);\
- Py_DECREF(_SOCK_STREAM);\
- Py_DECREF(_SOCK_DGRAM);
-
-typedef BOOL (WINAPI *LPFN_GLPI)
- (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
-
-// fix for mingw32, see
-// https://github.com/giampaolo/psutil/issues/351#c2
-typedef struct _DISK_PERFORMANCE_WIN_2008 {
- LARGE_INTEGER BytesRead;
- LARGE_INTEGER BytesWritten;
- LARGE_INTEGER ReadTime;
- LARGE_INTEGER WriteTime;
- LARGE_INTEGER IdleTime;
- DWORD ReadCount;
- DWORD WriteCount;
- DWORD QueueDepth;
- DWORD SplitCount;
- LARGE_INTEGER QueryTime;
- DWORD StorageDeviceNumber;
- WCHAR StorageManagerName[8];
-} DISK_PERFORMANCE_WIN_2008;
-
-// --- network connections mingw32 support
-#ifndef _IPRTRMIB_H
-typedef struct _MIB_TCP6ROW_OWNER_PID {
- UCHAR ucLocalAddr[16];
- DWORD dwLocalScopeId;
- DWORD dwLocalPort;
- UCHAR ucRemoteAddr[16];
- DWORD dwRemoteScopeId;
- DWORD dwRemotePort;
- DWORD dwState;
- DWORD dwOwningPid;
-} MIB_TCP6ROW_OWNER_PID, *PMIB_TCP6ROW_OWNER_PID;
-
-typedef struct _MIB_TCP6TABLE_OWNER_PID {
- DWORD dwNumEntries;
- MIB_TCP6ROW_OWNER_PID table[ANY_SIZE];
-} MIB_TCP6TABLE_OWNER_PID, *PMIB_TCP6TABLE_OWNER_PID;
-#endif
-
-#ifndef __IPHLPAPI_H__
-typedef struct in6_addr {
- union {
- UCHAR Byte[16];
- USHORT Word[8];
- } u;
-} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
-
-typedef enum _UDP_TABLE_CLASS {
- UDP_TABLE_BASIC,
- UDP_TABLE_OWNER_PID,
- UDP_TABLE_OWNER_MODULE
-} UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;
-
-typedef struct _MIB_UDPROW_OWNER_PID {
- DWORD dwLocalAddr;
- DWORD dwLocalPort;
- DWORD dwOwningPid;
-} MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
-
-typedef struct _MIB_UDPTABLE_OWNER_PID {
- DWORD dwNumEntries;
- MIB_UDPROW_OWNER_PID table[ANY_SIZE];
-} MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;
-#endif
-
-typedef struct _MIB_UDP6ROW_OWNER_PID {
- UCHAR ucLocalAddr[16];
- DWORD dwLocalScopeId;
- DWORD dwLocalPort;
- DWORD dwOwningPid;
-} MIB_UDP6ROW_OWNER_PID, *PMIB_UDP6ROW_OWNER_PID;
-
-typedef struct _MIB_UDP6TABLE_OWNER_PID {
- DWORD dwNumEntries;
- MIB_UDP6ROW_OWNER_PID table[ANY_SIZE];
-} MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;
-
-
-PIP_ADAPTER_ADDRESSES
-psutil_get_nic_addresses() {
- // allocate a 15 KB buffer to start with
- int outBufLen = 15000;
- DWORD dwRetVal = 0;
- ULONG attempts = 0;
- PIP_ADAPTER_ADDRESSES pAddresses = NULL;
-
- do {
- pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
- if (pAddresses == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
-
- dwRetVal = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses,
- &outBufLen);
- if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
- free(pAddresses);
- pAddresses = NULL;
- }
- else {
- break;
- }
-
- attempts++;
- } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (attempts < 3));
-
- if (dwRetVal != NO_ERROR) {
- PyErr_SetString(PyExc_RuntimeError, "GetAdaptersAddresses() failed.");
- return NULL;
- }
-
- return pAddresses;
-}
-
-
-/*
- * ============================================================================
- * Public Python API
- * ============================================================================
- */
-
-
-/*
- * Return a Python float representing the system uptime expressed in seconds
- * since the epoch.
- */
-static PyObject *
-psutil_boot_time(PyObject *self, PyObject *args)
-{
- double uptime;
- time_t pt;
- FILETIME fileTime;
- long long ll;
-
- GetSystemTimeAsFileTime(&fileTime);
-
- /*
- HUGE thanks to:
- http://johnstewien.spaces.live.com/blog/cns!E6885DB5CEBABBC8!831.entry
-
- This function converts the FILETIME structure to the 32 bit
- Unix time structure.
- The time_t is a 32-bit value for the number of seconds since
- January 1, 1970. A FILETIME is a 64-bit for the number of
- 100-nanosecond periods since January 1, 1601. Convert by
- subtracting the number of 100-nanosecond period betwee 01-01-1970
- and 01-01-1601, from time_t the divide by 1e+7 to get to the same
- base granularity.
- */
- ll = (((LONGLONG)(fileTime.dwHighDateTime)) << 32) \
- + fileTime.dwLowDateTime;
- pt = (time_t)((ll - 116444736000000000ull) / 10000000ull);
-
- // XXX - By using GetTickCount() time will wrap around to zero if the
- // system is run continuously for 49.7 days.
- uptime = GetTickCount() / 1000.00f;
- return Py_BuildValue("d", (double)pt - uptime);
-}
-
-
-/*
- * Return 1 if PID exists in the current process list, else 0.
- */
-static PyObject *
-psutil_pid_exists(PyObject *self, PyObject *args)
-{
- long pid;
- int status;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- status = psutil_pid_is_running(pid);
- if (-1 == status)
- return NULL; // exception raised in psutil_pid_is_running()
- return PyBool_FromLong(status);
-}
-
-
-/*
- * Return a Python list of all the PIDs running on the system.
- */
-static PyObject *
-psutil_pids(PyObject *self, PyObject *args)
-{
- DWORD *proclist = NULL;
- DWORD numberOfReturnedPIDs;
- DWORD i;
- PyObject *pid = NULL;
- PyObject *retlist = PyList_New(0);
-
- if (retlist == NULL)
- return NULL;
- proclist = psutil_get_pids(&numberOfReturnedPIDs);
- if (proclist == NULL)
- goto error;
-
- for (i = 0; i < numberOfReturnedPIDs; i++) {
- pid = Py_BuildValue("I", proclist[i]);
- if (!pid)
- goto error;
- if (PyList_Append(retlist, pid))
- goto error;
- Py_DECREF(pid);
- }
-
- // free C array allocated for PIDs
- free(proclist);
- return retlist;
-
-error:
- Py_XDECREF(pid);
- Py_DECREF(retlist);
- if (proclist != NULL)
- free(proclist);
- return NULL;
-}
-
-
-/*
- * Kill a process given its PID.
- */
-static PyObject *
-psutil_proc_kill(PyObject *self, PyObject *args)
-{
- HANDLE hProcess;
- long pid;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (pid == 0)
- return AccessDenied();
-
- hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
- if (hProcess == NULL) {
- if (GetLastError() == ERROR_INVALID_PARAMETER) {
- // see https://github.com/giampaolo/psutil/issues/24
- NoSuchProcess();
- }
- else {
- PyErr_SetFromWindowsErr(0);
- }
- return NULL;
- }
-
- // kill the process
- if (! TerminateProcess(hProcess, 0)) {
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hProcess);
- return NULL;
- }
-
- CloseHandle(hProcess);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Wait for process to terminate and return its exit code.
- */
-static PyObject *
-psutil_proc_wait(PyObject *self, PyObject *args)
-{
- HANDLE hProcess;
- DWORD ExitCode;
- DWORD retVal;
- long pid;
- long timeout;
-
- if (! PyArg_ParseTuple(args, "ll", &pid, &timeout))
- return NULL;
- if (pid == 0)
- return AccessDenied();
-
- hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
- FALSE, pid);
- if (hProcess == NULL) {
- if (GetLastError() == ERROR_INVALID_PARAMETER) {
- // no such process; we do not want to raise NSP but
- // return None instead.
- Py_RETURN_NONE;
- }
- else {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- }
-
- // wait until the process has terminated
- Py_BEGIN_ALLOW_THREADS
- retVal = WaitForSingleObject(hProcess, timeout);
- Py_END_ALLOW_THREADS
-
- if (retVal == WAIT_FAILED) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(GetLastError());
- }
- if (retVal == WAIT_TIMEOUT) {
- CloseHandle(hProcess);
- return Py_BuildValue("l", WAIT_TIMEOUT);
- }
-
- // get the exit code; note: subprocess module (erroneously?) uses
- // what returned by WaitForSingleObject
- if (GetExitCodeProcess(hProcess, &ExitCode) == 0) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(GetLastError());
- }
- CloseHandle(hProcess);
-#if PY_MAJOR_VERSION >= 3
- return PyLong_FromLong((long) ExitCode);
-#else
- return PyInt_FromLong((long) ExitCode);
-#endif
-}
-
-
-/*
- * Return a Python tuple (user_time, kernel_time)
- */
-static PyObject *
-psutil_proc_cpu_times(PyObject *self, PyObject *args)
-{
- long pid;
- HANDLE hProcess;
- FILETIME ftCreate, ftExit, ftKernel, ftUser;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL)
- return NULL;
- if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
- CloseHandle(hProcess);
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- // usually means the process has died so we throw a NoSuchProcess
- // here
- return NoSuchProcess();
- }
- else {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- }
-
- CloseHandle(hProcess);
-
- /*
- * User and kernel times are represented as a FILETIME structure
- * wich contains a 64-bit value representing the number of
- * 100-nanosecond intervals since January 1, 1601 (UTC):
- * http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
- * To convert it into a float representing the seconds that the
- * process has executed in user/kernel mode I borrowed the code
- * below from Python's Modules/posixmodule.c
- */
- return Py_BuildValue(
- "(dd)",
- (double)(ftUser.dwHighDateTime * 429.4967296 + \
- ftUser.dwLowDateTime * 1e-7),
- (double)(ftKernel.dwHighDateTime * 429.4967296 + \
- ftKernel.dwLowDateTime * 1e-7)
- );
-}
-
-
-/*
- * Return a Python float indicating the process create time expressed in
- * seconds since the epoch.
- */
-static PyObject *
-psutil_proc_create_time(PyObject *self, PyObject *args)
-{
- long pid;
- long long unix_time;
- DWORD exitCode;
- HANDLE hProcess;
- BOOL ret;
- FILETIME ftCreate, ftExit, ftKernel, ftUser;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- // special case for PIDs 0 and 4, return system boot time
- if (0 == pid || 4 == pid)
- return psutil_boot_time(NULL, NULL);
-
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL)
- return NULL;
- if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
- CloseHandle(hProcess);
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- // usually means the process has died so we throw a
- // NoSuchProcess here
- return NoSuchProcess();
- }
- else {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- }
-
- // Make sure the process is not gone as OpenProcess alone seems to be
- // unreliable in doing so (it seems a previous call to p.wait() makes
- // it unreliable).
- // This check is important as creation time is used to make sure the
- // process is still running.
- ret = GetExitCodeProcess(hProcess, &exitCode);
- CloseHandle(hProcess);
- if (ret != 0) {
- if (exitCode != STILL_ACTIVE)
- return NoSuchProcess();
- }
- else {
- // Ignore access denied as it means the process is still alive.
- // For all other errors, we want an exception.
- if (GetLastError() != ERROR_ACCESS_DENIED) {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- }
-
- /*
- Convert the FILETIME structure to a Unix time.
- It's the best I could find by googling and borrowing code here and there.
- The time returned has a precision of 1 second.
- */
- unix_time = ((LONGLONG)ftCreate.dwHighDateTime) << 32;
- unix_time += ftCreate.dwLowDateTime - 116444736000000000LL;
- unix_time /= 10000000;
- return Py_BuildValue("d", (double)unix_time);
-}
-
-
-
-/*
- * Return the number of logical CPUs.
- */
-static PyObject *
-psutil_cpu_count_logical(PyObject *self, PyObject *args)
-{
- SYSTEM_INFO system_info;
- system_info.dwNumberOfProcessors = 0;
-
- GetSystemInfo(&system_info);
- if (system_info.dwNumberOfProcessors == 0)
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("I", system_info.dwNumberOfProcessors);
-}
-
-
-/*
- * Return the number of physical CPU cores.
- */
-static PyObject *
-psutil_cpu_count_phys(PyObject *self, PyObject *args)
-{
- LPFN_GLPI glpi;
- DWORD rc;
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
- DWORD length = 0;
- DWORD offset = 0;
- int ncpus = 0;
-
- glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
- "GetLogicalProcessorInformation");
- if (glpi == NULL)
- goto return_none;
-
- while (1) {
- rc = glpi(buffer, &length);
- if (rc == FALSE) {
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- if (buffer)
- free(buffer);
- buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(
- length);
- if (NULL == buffer) {
- PyErr_NoMemory();
- return NULL;
- }
- }
- else {
- goto return_none;
- }
- }
- else {
- break;
- }
- }
-
- ptr = buffer;
- while (offset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= length) {
- if (ptr->Relationship == RelationProcessorCore)
- ncpus += 1;
- offset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
- ptr++;
- }
-
- free(buffer);
- if (ncpus == 0)
- goto return_none;
- else
- return Py_BuildValue("i", ncpus);
-
-return_none:
- // mimic os.cpu_count()
- if (buffer != NULL)
- free(buffer);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Return process cmdline as a Python list of cmdline arguments.
- */
-static PyObject *
-psutil_proc_cmdline(PyObject *self, PyObject *args) {
- long pid;
- int pid_return;
- PyObject *arglist;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if ((pid == 0) || (pid == 4))
- return Py_BuildValue("[]");
-
- pid_return = psutil_pid_is_running(pid);
- if (pid_return == 0)
- return NoSuchProcess();
- if (pid_return == -1)
- return NULL;
-
- // XXX the assumptio below probably needs to go away
-
- // May fail any of several ReadProcessMemory calls etc. and
- // not indicate a real problem so we ignore any errors and
- // just live without commandline.
- arglist = psutil_get_arg_list(pid);
- if ( NULL == arglist ) {
- // carry on anyway, clear any exceptions too
- PyErr_Clear();
- return Py_BuildValue("[]");
- }
-
- return arglist;
-}
-
-
-/*
- * Return process executable path.
- */
-static PyObject *
-psutil_proc_exe(PyObject *self, PyObject *args) {
- long pid;
- HANDLE hProcess;
- wchar_t exe[MAX_PATH];
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
- if (NULL == hProcess)
- return NULL;
- if (GetProcessImageFileNameW(hProcess, exe, MAX_PATH) == 0) {
- CloseHandle(hProcess);
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- CloseHandle(hProcess);
- return Py_BuildValue("u", exe);
-}
-
-
-/*
- * Return process base name.
- * Note: psutil_proc_exe() is attempted first because it's faster
- * but it raise AccessDenied for processes owned by other users
- * in which case we fall back on using this.
- */
-static PyObject *
-psutil_proc_name(PyObject *self, PyObject *args) {
- long pid;
- int ok;
- PROCESSENTRY32 pentry;
- HANDLE hSnapShot;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
- if (hSnapShot == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- pentry.dwSize = sizeof(PROCESSENTRY32);
- ok = Process32First(hSnapShot, &pentry);
- if (! ok) {
- CloseHandle(hSnapShot);
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- while (ok) {
- if (pentry.th32ProcessID == pid) {
- CloseHandle(hSnapShot);
- return Py_BuildValue("s", pentry.szExeFile);
- }
- ok = Process32Next(hSnapShot, &pentry);
- }
-
- CloseHandle(hSnapShot);
- NoSuchProcess();
- return NULL;
-}
-
-
-/*
- * Return process memory information as a Python tuple.
- */
-static PyObject *
-psutil_proc_memory_info(PyObject *self, PyObject *args)
-{
- HANDLE hProcess;
- DWORD pid;
-#if (_WIN32_WINNT >= 0x0501) // Windows XP with SP2
- PROCESS_MEMORY_COUNTERS_EX cnt;
-#else
- PROCESS_MEMORY_COUNTERS cnt;
-#endif
- SIZE_T private = 0;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- hProcess = psutil_handle_from_pid(pid);
- if (NULL == hProcess)
- return NULL;
-
- if (! GetProcessMemoryInfo(hProcess, (PPROCESS_MEMORY_COUNTERS)&cnt,
- sizeof(cnt))) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(0);
- }
-
-#if (_WIN32_WINNT >= 0x0501) // Windows XP with SP2
- private = cnt.PrivateUsage;
-#endif
-
- CloseHandle(hProcess);
-
- // PROCESS_MEMORY_COUNTERS values are defined as SIZE_T which on 64bits
- // is an (unsigned long long) and on 32bits is an (unsigned int).
- // "_WIN64" is defined if we're running a 64bit Python interpreter not
- // exclusively if the *system* is 64bit.
-#if defined(_WIN64)
- return Py_BuildValue(
- "(kKKKKKKKKK)",
- cnt.PageFaultCount, // unsigned long
- (unsigned long long)cnt.PeakWorkingSetSize,
- (unsigned long long)cnt.WorkingSetSize,
- (unsigned long long)cnt.QuotaPeakPagedPoolUsage,
- (unsigned long long)cnt.QuotaPagedPoolUsage,
- (unsigned long long)cnt.QuotaPeakNonPagedPoolUsage,
- (unsigned long long)cnt.QuotaNonPagedPoolUsage,
- (unsigned long long)cnt.PagefileUsage,
- (unsigned long long)cnt.PeakPagefileUsage,
- (unsigned long long)private);
-#else
- return Py_BuildValue(
- "(kIIIIIIIII)",
- cnt.PageFaultCount, // unsigned long
- (unsigned int)cnt.PeakWorkingSetSize,
- (unsigned int)cnt.WorkingSetSize,
- (unsigned int)cnt.QuotaPeakPagedPoolUsage,
- (unsigned int)cnt.QuotaPagedPoolUsage,
- (unsigned int)cnt.QuotaPeakNonPagedPoolUsage,
- (unsigned int)cnt.QuotaNonPagedPoolUsage,
- (unsigned int)cnt.PagefileUsage,
- (unsigned int)cnt.PeakPagefileUsage,
- (unsigned int)private);
-#endif
-}
-
-
-/*
- * Alternative implementation of the one above but bypasses ACCESS DENIED.
- */
-static PyObject *
-psutil_proc_memory_info_2(PyObject *self, PyObject *args)
-{
- DWORD pid;
- PSYSTEM_PROCESS_INFORMATION process;
- PVOID buffer;
- SIZE_T private;
- unsigned long pfault_count;
-
-#if defined(_WIN64)
- unsigned long long m1, m2, m3, m4, m5, m6, m7, m8;
-#else
- unsigned int m1, m2, m3, m4, m5, m6, m7, m8;
-#endif
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_get_proc_info(pid, &process, &buffer))
- return NULL;
-
-#if (_WIN32_WINNT >= 0x0501) // Windows XP with SP2
- private = process->PrivatePageCount;
-#else
- private = 0;
-#endif
- pfault_count = process->PageFaultCount;
-
- m1 = process->PeakWorkingSetSize;
- m2 = process->WorkingSetSize;
- m3 = process->QuotaPeakPagedPoolUsage;
- m4 = process->QuotaPagedPoolUsage;
- m5 = process->QuotaPeakNonPagedPoolUsage;
- m6 = process->QuotaNonPagedPoolUsage;
- m7 = process->PagefileUsage;
- m8 = process->PeakPagefileUsage;
-
- free(buffer);
-
- // SYSTEM_PROCESS_INFORMATION values are defined as SIZE_T which on 64
- // bits is an (unsigned long long) and on 32bits is an (unsigned int).
- // "_WIN64" is defined if we're running a 64bit Python interpreter not
- // exclusively if the *system* is 64bit.
-#if defined(_WIN64)
- return Py_BuildValue("(kKKKKKKKKK)",
-#else
- return Py_BuildValue("(kIIIIIIIII)",
-#endif
- pfault_count, m1, m2, m3, m4, m5, m6, m7, m8, private);
-}
-
-
-/*
- * Return a Python integer indicating the total amount of physical memory
- * in bytes.
- */
-static PyObject *
-psutil_virtual_mem(PyObject *self, PyObject *args)
-{
- MEMORYSTATUSEX memInfo;
- memInfo.dwLength = sizeof(MEMORYSTATUSEX);
-
- if (! GlobalMemoryStatusEx(&memInfo))
- return PyErr_SetFromWindowsErr(0);
- return Py_BuildValue("(LLLLLL)",
- memInfo.ullTotalPhys, // total
- memInfo.ullAvailPhys, // avail
- memInfo.ullTotalPageFile, // total page file
- memInfo.ullAvailPageFile, // avail page file
- memInfo.ullTotalVirtual, // total virtual
- memInfo.ullAvailVirtual); // avail virtual
-}
-
-
-/*
- * Retrieves system CPU timing information as a (user, system, idle)
- * tuple. On a multiprocessor system, the values returned are the
- * sum of the designated times across all processors.
- */
-static PyObject *
-psutil_cpu_times(PyObject *self, PyObject *args)
-{
- float idle, kernel, user, system;
- FILETIME idle_time, kernel_time, user_time;
-
- if (!GetSystemTimes(&idle_time, &kernel_time, &user_time))
- return PyErr_SetFromWindowsErr(0);
-
- idle = (float)((HI_T * idle_time.dwHighDateTime) + \
- (LO_T * idle_time.dwLowDateTime));
- user = (float)((HI_T * user_time.dwHighDateTime) + \
- (LO_T * user_time.dwLowDateTime));
- kernel = (float)((HI_T * kernel_time.dwHighDateTime) + \
- (LO_T * kernel_time.dwLowDateTime));
-
- // Kernel time includes idle time.
- // We return only busy kernel time subtracting idle time from
- // kernel time.
- system = (kernel - idle);
- return Py_BuildValue("(fff)", user, system, idle);
-}
-
-
-/*
- * Same as above but for all system CPUs.
- */
-static PyObject *
-psutil_per_cpu_times(PyObject *self, PyObject *args)
-{
- float idle, kernel, user;
- typedef DWORD (_stdcall * NTQSI_PROC) (int, PVOID, ULONG, PULONG);
- NTQSI_PROC NtQuerySystemInformation;
- HINSTANCE hNtDll;
- SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
- SYSTEM_INFO si;
- UINT i;
- PyObject *arg = NULL;
- PyObject *retlist = PyList_New(0);
-
- if (retlist == NULL)
- return NULL;
-
- // dynamic linking is mandatory to use NtQuerySystemInformation
- hNtDll = LoadLibrary(TEXT("ntdll.dll"));
- if (hNtDll != NULL) {
- // gets NtQuerySystemInformation address
- NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
- hNtDll, "NtQuerySystemInformation");
-
- if (NtQuerySystemInformation != NULL)
- {
- // retrives number of processors
- GetSystemInfo(&si);
-
- // allocates an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
- // structures, one per processor
- sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
- malloc(si.dwNumberOfProcessors * \
- sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
- if (sppi != NULL)
- {
- // gets cpu time informations
- if (0 == NtQuerySystemInformation(
- SystemProcessorPerformanceInformation,
- sppi,
- si.dwNumberOfProcessors * sizeof
- (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
- NULL)
- )
- {
- // computes system global times summing each
- // processor value
- idle = user = kernel = 0;
- for (i = 0; i < si.dwNumberOfProcessors; i++) {
- arg = NULL;
- user = (float)((HI_T * sppi[i].UserTime.HighPart) +
- (LO_T * sppi[i].UserTime.LowPart));
- idle = (float)((HI_T * sppi[i].IdleTime.HighPart) +
- (LO_T * sppi[i].IdleTime.LowPart));
- kernel = (float)((HI_T * sppi[i].KernelTime.HighPart) +
- (LO_T * sppi[i].KernelTime.LowPart));
- // kernel time includes idle time on windows
- // we return only busy kernel time subtracting
- // idle time from kernel time
- arg = Py_BuildValue("(ddd)",
- user,
- kernel - idle,
- idle);
- if (!arg)
- goto error;
- if (PyList_Append(retlist, arg))
- goto error;
- Py_DECREF(arg);
- }
- free(sppi);
- FreeLibrary(hNtDll);
- return retlist;
-
- } // END NtQuerySystemInformation
- } // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
- } // END GetProcAddress
- } // END LoadLibrary
- goto error;
-
-error:
- Py_XDECREF(arg);
- Py_DECREF(retlist);
- if (sppi)
- free(sppi);
- if (hNtDll)
- FreeLibrary(hNtDll);
- PyErr_SetFromWindowsErr(0);
- return NULL;
-}
-
-
-/*
- * Return process current working directory as a Python string.
- */
-
-static PyObject *
-psutil_proc_cwd(PyObject *self, PyObject *args)
-{
- long pid;
- HANDLE processHandle = NULL;
- PVOID pebAddress;
- PVOID rtlUserProcParamsAddress;
- UNICODE_STRING currentDirectory;
- WCHAR *currentDirectoryContent = NULL;
- PyObject *returnPyObj = NULL;
- PyObject *cwd_from_wchar = NULL;
- PyObject *cwd = NULL;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- processHandle = psutil_handle_from_pid(pid);
- if (processHandle == NULL)
- return NULL;
-
- pebAddress = psutil_get_peb_address(processHandle);
-
- // get the address of ProcessParameters
-#ifdef _WIN64
- if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 32,
- &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
-#else
- if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10,
- &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
-#endif
- {
- CloseHandle(processHandle);
- if (GetLastError() == ERROR_PARTIAL_COPY) {
- // this occurs quite often with system processes
- return AccessDenied();
- }
- else {
- return PyErr_SetFromWindowsErr(0);
- }
- }
-
- // Read the currentDirectory UNICODE_STRING structure.
- // 0x24 refers to "CurrentDirectoryPath" of RTL_USER_PROCESS_PARAMETERS
- // structure, see:
- // http://wj32.wordpress.com/2009/01/24/
- // howto-get-the-command-line-of-processes/
-#ifdef _WIN64
- if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 56,
- &currentDirectory, sizeof(currentDirectory), NULL))
-#else
- if (!ReadProcessMemory(processHandle,
- (PCHAR)rtlUserProcParamsAddress + 0x24,
- &currentDirectory, sizeof(currentDirectory), NULL))
-#endif
- {
- CloseHandle(processHandle);
- if (GetLastError() == ERROR_PARTIAL_COPY) {
- // this occurs quite often with system processes
- return AccessDenied();
- }
- else {
- return PyErr_SetFromWindowsErr(0);
- }
- }
-
- // allocate memory to hold cwd
- currentDirectoryContent = (WCHAR *)malloc(currentDirectory.Length + 1);
- if (currentDirectoryContent == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- // read cwd
- if (!ReadProcessMemory(processHandle, currentDirectory.Buffer,
- currentDirectoryContent, currentDirectory.Length,
- NULL))
- {
- if (GetLastError() == ERROR_PARTIAL_COPY) {
- // this occurs quite often with system processes
- AccessDenied();
- }
- else {
- PyErr_SetFromWindowsErr(0);
- }
- goto error;
- }
-
- // null-terminate the string to prevent wcslen from returning
- // incorrect length the length specifier is in characters, but
- // currentDirectory.Length is in bytes
- currentDirectoryContent[(currentDirectory.Length / sizeof(WCHAR))] = '\0';
-
- // convert wchar array to a Python unicode string, and then to UTF8
- cwd_from_wchar = PyUnicode_FromWideChar(currentDirectoryContent,
- wcslen(currentDirectoryContent));
- if (cwd_from_wchar == NULL)
- goto error;
-
-#if PY_MAJOR_VERSION >= 3
- cwd = PyUnicode_FromObject(cwd_from_wchar);
-#else
- cwd = PyUnicode_AsUTF8String(cwd_from_wchar);
-#endif
- if (cwd == NULL)
- goto error;
-
- // decrement the reference count on our temp unicode str to avoid
- // mem leak
- returnPyObj = Py_BuildValue("N", cwd);
- if (!returnPyObj)
- goto error;
-
- Py_DECREF(cwd_from_wchar);
-
- CloseHandle(processHandle);
- free(currentDirectoryContent);
- return returnPyObj;
-
-error:
- Py_XDECREF(cwd_from_wchar);
- Py_XDECREF(cwd);
- Py_XDECREF(returnPyObj);
- if (currentDirectoryContent != NULL)
- free(currentDirectoryContent);
- if (processHandle != NULL)
- CloseHandle(processHandle);
- return NULL;
-}
-
-
-/*
- * Resume or suspends a process
- */
-int
-psutil_proc_suspend_or_resume(DWORD pid, int suspend)
-{
- // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx
- HANDLE hThreadSnap = NULL;
- THREADENTRY32 te32 = {0};
-
- if (pid == 0) {
- AccessDenied();
- return FALSE;
- }
-
- hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (hThreadSnap == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
- return FALSE;
- }
-
- // Fill in the size of the structure before using it
- te32.dwSize = sizeof(THREADENTRY32);
-
- if (! Thread32First(hThreadSnap, &te32)) {
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hThreadSnap);
- return FALSE;
- }
-
- // Walk the thread snapshot to find all threads of the process.
- // If the thread belongs to the process, add its information
- // to the display list.
- do
- {
- if (te32.th32OwnerProcessID == pid)
- {
- HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE,
- te32.th32ThreadID);
- if (hThread == NULL) {
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hThread);
- CloseHandle(hThreadSnap);
- return FALSE;
- }
- if (suspend == 1)
- {
- if (SuspendThread(hThread) == (DWORD) - 1) {
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hThread);
- CloseHandle(hThreadSnap);
- return FALSE;
- }
- }
- else
- {
- if (ResumeThread(hThread) == (DWORD) - 1) {
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hThread);
- CloseHandle(hThreadSnap);
- return FALSE;
- }
- }
- CloseHandle(hThread);
- }
- } while (Thread32Next(hThreadSnap, &te32));
-
- CloseHandle(hThreadSnap);
- return TRUE;
-}
-
-
-static PyObject *
-psutil_proc_suspend(PyObject *self, PyObject *args)
-{
- long pid;
- int suspend = 1;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_suspend_or_resume(pid, suspend))
- return NULL;
- Py_RETURN_NONE;
-}
-
-
-static PyObject *
-psutil_proc_resume(PyObject *self, PyObject *args)
-{
- long pid;
- int suspend = 0;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_proc_suspend_or_resume(pid, suspend))
- return NULL;
- Py_RETURN_NONE;
-}
-
-
-static PyObject *
-psutil_proc_threads(PyObject *self, PyObject *args)
-{
- HANDLE hThread;
- THREADENTRY32 te32 = {0};
- long pid;
- int pid_return;
- int rc;
- FILETIME ftDummy, ftKernel, ftUser;
- PyObject *retList = PyList_New(0);
- PyObject *pyTuple = NULL;
- HANDLE hThreadSnap = NULL;
-
- if (retList == NULL)
- return NULL;
- if (! PyArg_ParseTuple(args, "l", &pid))
- goto error;
- if (pid == 0) {
- // raise AD instead of returning 0 as procexp is able to
- // retrieve useful information somehow
- AccessDenied();
- goto error;
- }
-
- pid_return = psutil_pid_is_running(pid);
- if (pid_return == 0) {
- NoSuchProcess();
- goto error;
- }
- if (pid_return == -1)
- goto error;
-
- hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (hThreadSnap == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- // Fill in the size of the structure before using it
- te32.dwSize = sizeof(THREADENTRY32);
-
- if (! Thread32First(hThreadSnap, &te32)) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- // Walk the thread snapshot to find all threads of the process.
- // If the thread belongs to the process, increase the counter.
- do {
- if (te32.th32OwnerProcessID == pid) {
- pyTuple = NULL;
- hThread = NULL;
- hThread = OpenThread(THREAD_QUERY_INFORMATION,
- FALSE, te32.th32ThreadID);
- if (hThread == NULL) {
- // thread has disappeared on us
- continue;
- }
-
- rc = GetThreadTimes(hThread, &ftDummy, &ftDummy, &ftKernel,
- &ftUser);
- if (rc == 0) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- /*
- * User and kernel times are represented as a FILETIME structure
- * wich contains a 64-bit value representing the number of
- * 100-nanosecond intervals since January 1, 1601 (UTC):
- * http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
- * To convert it into a float representing the seconds that the
- * process has executed in user/kernel mode I borrowed the code
- * below from Python's Modules/posixmodule.c
- */
- pyTuple = Py_BuildValue(
- "kdd",
- te32.th32ThreadID,
- (double)(ftUser.dwHighDateTime * 429.4967296 + \
- ftUser.dwLowDateTime * 1e-7),
- (double)(ftKernel.dwHighDateTime * 429.4967296 + \
- ftKernel.dwLowDateTime * 1e-7));
- if (!pyTuple)
- goto error;
- if (PyList_Append(retList, pyTuple))
- goto error;
- Py_DECREF(pyTuple);
-
- CloseHandle(hThread);
- }
- } while (Thread32Next(hThreadSnap, &te32));
-
- CloseHandle(hThreadSnap);
- return retList;
-
-error:
- Py_XDECREF(pyTuple);
- Py_DECREF(retList);
- if (hThread != NULL)
- CloseHandle(hThread);
- if (hThreadSnap != NULL)
- CloseHandle(hThreadSnap);
- return NULL;
-}
-
-
-static PyObject *
-psutil_proc_open_files(PyObject *self, PyObject *args)
-{
- long pid;
- HANDLE processHandle;
- DWORD access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
- PyObject *filesList;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- processHandle = psutil_handle_from_pid_waccess(pid, access);
- if (processHandle == NULL)
- return NULL;
- filesList = psutil_get_open_files(pid, processHandle);
- CloseHandle(processHandle);
- if (filesList == NULL)
- return PyErr_SetFromWindowsErr(0);
- return filesList;
-}
-
-
-/*
- Accept a filename's drive in native format like "\Device\HarddiskVolume1\"
- and return the corresponding drive letter (e.g. "C:\\").
- If no match is found return an empty string.
-*/
-static PyObject *
-psutil_win32_QueryDosDevice(PyObject *self, PyObject *args)
-{
- LPCTSTR lpDevicePath;
- TCHAR d = TEXT('A');
- TCHAR szBuff[5];
-
- if (!PyArg_ParseTuple(args, "s", &lpDevicePath))
- return NULL;
-
- while (d <= TEXT('Z')) {
- TCHAR szDeviceName[3] = {d, TEXT(':'), TEXT('\0')};
- TCHAR szTarget[512] = {0};
- if (QueryDosDevice(szDeviceName, szTarget, 511) != 0) {
- if (_tcscmp(lpDevicePath, szTarget) == 0) {
- _stprintf_s(szBuff, _countof(szBuff), TEXT("%c:"), d);
- return Py_BuildValue("s", szBuff);
- }
- }
- d++;
- }
- return Py_BuildValue("s", "");
-}
-
-
-/*
- * Return process username as a "DOMAIN//USERNAME" string.
- */
-static PyObject *
-psutil_proc_username(PyObject *self, PyObject *args)
-{
- long pid;
- HANDLE processHandle;
- HANDLE tokenHandle;
- PTOKEN_USER user;
- ULONG bufferSize;
- PTSTR name;
- ULONG nameSize;
- PTSTR domainName;
- ULONG domainNameSize;
- SID_NAME_USE nameUse;
- PTSTR fullName;
- PyObject *returnObject;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- processHandle = psutil_handle_from_pid_waccess(
- pid, PROCESS_QUERY_INFORMATION);
- if (processHandle == NULL)
- return NULL;
-
- if (!OpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)) {
- CloseHandle(processHandle);
- return PyErr_SetFromWindowsErr(0);
- }
-
- CloseHandle(processHandle);
-
- // Get the user SID.
-
- bufferSize = 0x100;
- user = malloc(bufferSize);
- if (user == NULL)
- return PyErr_NoMemory();
-
- if (!GetTokenInformation(tokenHandle, TokenUser, user, bufferSize,
- &bufferSize))
- {
- free(user);
- user = malloc(bufferSize);
- if (user == NULL) {
- CloseHandle(tokenHandle);
- return PyErr_NoMemory();
- }
- if (!GetTokenInformation(tokenHandle, TokenUser, user, bufferSize,
- &bufferSize))
- {
- free(user);
- CloseHandle(tokenHandle);
- return PyErr_SetFromWindowsErr(0);
- }
- }
-
- CloseHandle(tokenHandle);
-
- // resolve the SID to a name
- nameSize = 0x100;
- domainNameSize = 0x100;
-
- name = malloc(nameSize * sizeof(TCHAR));
- if (name == NULL)
- return PyErr_NoMemory();
- domainName = malloc(domainNameSize * sizeof(TCHAR));
- if (domainName == NULL)
- return PyErr_NoMemory();
-
- if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
- &domainNameSize, &nameUse))
- {
- free(name);
- free(domainName);
- name = malloc(nameSize * sizeof(TCHAR));
- if (name == NULL)
- return PyErr_NoMemory();
- domainName = malloc(domainNameSize * sizeof(TCHAR));
- if (domainName == NULL)
- return PyErr_NoMemory();
- if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize,
- domainName, &domainNameSize, &nameUse))
- {
- free(name);
- free(domainName);
- free(user);
-
- return PyErr_SetFromWindowsErr(0);
- }
- }
-
- nameSize = _tcslen(name);
- domainNameSize = _tcslen(domainName);
-
- // build the full username string
- fullName = malloc((domainNameSize + 1 + nameSize + 1) * sizeof(TCHAR));
- if (fullName == NULL) {
- free(name);
- free(domainName);
- free(user);
- return PyErr_NoMemory();
- }
- memcpy(fullName, domainName, domainNameSize);
- fullName[domainNameSize] = '\\';
- memcpy(&fullName[domainNameSize + 1], name, nameSize);
- fullName[domainNameSize + 1 + nameSize] = '\0';
-
- returnObject = PyUnicode_Decode(
- fullName, _tcslen(fullName), Py_FileSystemDefaultEncoding, "replace");
-
- free(fullName);
- free(name);
- free(domainName);
- free(user);
-
- return returnObject;
-}
-
-
-/*
- * Return a list of network connections opened by a process
- */
-static PyObject *
-psutil_net_connections(PyObject *self, PyObject *args)
-{
- static long null_address[4] = { 0, 0, 0, 0 };
-
- unsigned long pid;
- PyObject *connectionsList;
- PyObject *connectionTuple = NULL;
- PyObject *af_filter = NULL;
- PyObject *type_filter = NULL;
-
- PyObject *_AF_INET = PyLong_FromLong((long)AF_INET);
- PyObject *_AF_INET6 = PyLong_FromLong((long)AF_INET6);
- PyObject *_SOCK_STREAM = PyLong_FromLong((long)SOCK_STREAM);
- PyObject *_SOCK_DGRAM = PyLong_FromLong((long)SOCK_DGRAM);
-
- typedef PSTR (NTAPI * _RtlIpv4AddressToStringA)(struct in_addr *, PSTR);
- _RtlIpv4AddressToStringA rtlIpv4AddressToStringA;
- typedef PSTR (NTAPI * _RtlIpv6AddressToStringA)(struct in6_addr *, PSTR);
- _RtlIpv6AddressToStringA rtlIpv6AddressToStringA;
- typedef DWORD (WINAPI * _GetExtendedTcpTable)(PVOID, PDWORD, BOOL, ULONG,
- TCP_TABLE_CLASS, ULONG);
- _GetExtendedTcpTable getExtendedTcpTable;
- typedef DWORD (WINAPI * _GetExtendedUdpTable)(PVOID, PDWORD, BOOL, ULONG,
- UDP_TABLE_CLASS, ULONG);
- _GetExtendedUdpTable getExtendedUdpTable;
- PVOID table = NULL;
- DWORD tableSize;
- PMIB_TCPTABLE_OWNER_PID tcp4Table;
- PMIB_UDPTABLE_OWNER_PID udp4Table;
- PMIB_TCP6TABLE_OWNER_PID tcp6Table;
- PMIB_UDP6TABLE_OWNER_PID udp6Table;
- ULONG i;
- CHAR addressBufferLocal[65];
- PyObject *addressTupleLocal = NULL;
- CHAR addressBufferRemote[65];
- PyObject *addressTupleRemote = NULL;
-
- if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
- _psutil_conn_decref_objs();
- return NULL;
- }
-
- if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
- _psutil_conn_decref_objs();
- PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
- return NULL;
- }
-
- if (pid != -1) {
- if (psutil_pid_is_running(pid) == 0) {
- _psutil_conn_decref_objs();
- return NoSuchProcess();
- }
- }
-
- // Import some functions.
- {
- HMODULE ntdll;
- HMODULE iphlpapi;
-
- ntdll = LoadLibrary(TEXT("ntdll.dll"));
- rtlIpv4AddressToStringA = (_RtlIpv4AddressToStringA)GetProcAddress(
- ntdll, "RtlIpv4AddressToStringA");
- rtlIpv6AddressToStringA = (_RtlIpv6AddressToStringA)GetProcAddress(
- ntdll, "RtlIpv6AddressToStringA");
- /* TODO: Check these two function pointers */
-
- iphlpapi = LoadLibrary(TEXT("iphlpapi.dll"));
- getExtendedTcpTable = (_GetExtendedTcpTable)GetProcAddress(iphlpapi,
- "GetExtendedTcpTable");
- getExtendedUdpTable = (_GetExtendedUdpTable)GetProcAddress(iphlpapi,
- "GetExtendedUdpTable");
- FreeLibrary(ntdll);
- FreeLibrary(iphlpapi);
- }
-
- if ((getExtendedTcpTable == NULL) || (getExtendedUdpTable == NULL)) {
- PyErr_SetString(PyExc_NotImplementedError,
- "feature not supported on this Windows version");
- _psutil_conn_decref_objs();
- return NULL;
- }
-
- connectionsList = PyList_New(0);
- if (connectionsList == NULL) {
- _psutil_conn_decref_objs();
- return NULL;
- }
-
- // TCP IPv4
-
- if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
- (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
- {
- table = NULL;
- connectionTuple = NULL;
- addressTupleLocal = NULL;
- addressTupleRemote = NULL;
- tableSize = 0;
- getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
- TCP_TABLE_OWNER_PID_ALL, 0);
-
- table = malloc(tableSize);
- if (table == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
- TCP_TABLE_OWNER_PID_ALL, 0) == 0)
- {
- tcp4Table = table;
-
- for (i = 0; i < tcp4Table->dwNumEntries; i++)
- {
- if (pid != -1) {
- if (tcp4Table->table[i].dwOwningPid != pid) {
- continue;
- }
- }
-
- if (tcp4Table->table[i].dwLocalAddr != 0 ||
- tcp4Table->table[i].dwLocalPort != 0)
- {
- struct in_addr addr;
-
- addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
- rtlIpv4AddressToStringA(&addr, addressBufferLocal);
- addressTupleLocal = Py_BuildValue(
- "(si)",
- addressBufferLocal,
- BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
- }
- else {
- addressTupleLocal = PyTuple_New(0);
- }
-
- if (addressTupleLocal == NULL)
- goto error;
-
- // On Windows <= XP, remote addr is filled even if socket
- // is in LISTEN mode in which case we just ignore it.
- if ((tcp4Table->table[i].dwRemoteAddr != 0 ||
- tcp4Table->table[i].dwRemotePort != 0) &&
- (tcp4Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
- {
- struct in_addr addr;
-
- addr.S_un.S_addr = tcp4Table->table[i].dwRemoteAddr;
- rtlIpv4AddressToStringA(&addr, addressBufferRemote);
- addressTupleRemote = Py_BuildValue(
- "(si)",
- addressBufferRemote,
- BYTESWAP_USHORT(tcp4Table->table[i].dwRemotePort));
- }
- else
- {
- addressTupleRemote = PyTuple_New(0);
- }
-
- if (addressTupleRemote == NULL)
- goto error;
-
- connectionTuple = Py_BuildValue(
- "(iiiNNiI)",
- -1,
- AF_INET,
- SOCK_STREAM,
- addressTupleLocal,
- addressTupleRemote,
- tcp4Table->table[i].dwState,
- tcp4Table->table[i].dwOwningPid);
- if (!connectionTuple)
- goto error;
- if (PyList_Append(connectionsList, connectionTuple))
- goto error;
- Py_DECREF(connectionTuple);
- }
- }
-
- free(table);
- }
-
- // TCP IPv6
-
- if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
- (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
- {
- table = NULL;
- connectionTuple = NULL;
- addressTupleLocal = NULL;
- addressTupleRemote = NULL;
- tableSize = 0;
- getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
- TCP_TABLE_OWNER_PID_ALL, 0);
-
- table = malloc(tableSize);
- if (table == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
- TCP_TABLE_OWNER_PID_ALL, 0) == 0)
- {
- tcp6Table = table;
-
- for (i = 0; i < tcp6Table->dwNumEntries; i++)
- {
- if (pid != -1) {
- if (tcp6Table->table[i].dwOwningPid != pid) {
- continue;
- }
- }
-
- if (memcmp(tcp6Table->table[i].ucLocalAddr, null_address, 16)
- != 0 || tcp6Table->table[i].dwLocalPort != 0)
- {
- struct in6_addr addr;
-
- memcpy(&addr, tcp6Table->table[i].ucLocalAddr, 16);
- rtlIpv6AddressToStringA(&addr, addressBufferLocal);
- addressTupleLocal = Py_BuildValue(
- "(si)",
- addressBufferLocal,
- BYTESWAP_USHORT(tcp6Table->table[i].dwLocalPort));
- }
- else
- {
- addressTupleLocal = PyTuple_New(0);
- }
-
- if (addressTupleLocal == NULL)
- goto error;
-
- // On Windows <= XP, remote addr is filled even if socket
- // is in LISTEN mode in which case we just ignore it.
- if ((memcmp(tcp6Table->table[i].ucRemoteAddr, null_address, 16)
- != 0 ||
- tcp6Table->table[i].dwRemotePort != 0) &&
- (tcp6Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
- {
- struct in6_addr addr;
-
- memcpy(&addr, tcp6Table->table[i].ucRemoteAddr, 16);
- rtlIpv6AddressToStringA(&addr, addressBufferRemote);
- addressTupleRemote = Py_BuildValue(
- "(si)",
- addressBufferRemote,
- BYTESWAP_USHORT(tcp6Table->table[i].dwRemotePort));
- }
- else
- {
- addressTupleRemote = PyTuple_New(0);
- }
-
- if (addressTupleRemote == NULL)
- goto error;
-
- connectionTuple = Py_BuildValue(
- "(iiiNNiI)",
- -1,
- AF_INET6,
- SOCK_STREAM,
- addressTupleLocal,
- addressTupleRemote,
- tcp6Table->table[i].dwState,
- tcp6Table->table[i].dwOwningPid);
- if (!connectionTuple)
- goto error;
- if (PyList_Append(connectionsList, connectionTuple))
- goto error;
- Py_DECREF(connectionTuple);
- }
- }
-
- free(table);
- }
-
- // UDP IPv4
-
- if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
- (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
- {
- table = NULL;
- connectionTuple = NULL;
- addressTupleLocal = NULL;
- addressTupleRemote = NULL;
- tableSize = 0;
- getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
- UDP_TABLE_OWNER_PID, 0);
-
- table = malloc(tableSize);
- if (table == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
- UDP_TABLE_OWNER_PID, 0) == 0)
- {
- udp4Table = table;
-
- for (i = 0; i < udp4Table->dwNumEntries; i++)
- {
- if (pid != -1) {
- if (udp4Table->table[i].dwOwningPid != pid) {
- continue;
- }
- }
-
- if (udp4Table->table[i].dwLocalAddr != 0 ||
- udp4Table->table[i].dwLocalPort != 0)
- {
- struct in_addr addr;
-
- addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
- rtlIpv4AddressToStringA(&addr, addressBufferLocal);
- addressTupleLocal = Py_BuildValue(
- "(si)",
- addressBufferLocal,
- BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
- }
- else {
- addressTupleLocal = PyTuple_New(0);
- }
-
- if (addressTupleLocal == NULL)
- goto error;
-
- connectionTuple = Py_BuildValue(
- "(iiiNNiI)",
- -1,
- AF_INET,
- SOCK_DGRAM,
- addressTupleLocal,
- PyTuple_New(0),
- PSUTIL_CONN_NONE,
- udp4Table->table[i].dwOwningPid);
- if (!connectionTuple)
- goto error;
- if (PyList_Append(connectionsList, connectionTuple))
- goto error;
- Py_DECREF(connectionTuple);
- }
- }
-
- free(table);
- }
-
- // UDP IPv6
-
- if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
- (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
- {
- table = NULL;
- connectionTuple = NULL;
- addressTupleLocal = NULL;
- addressTupleRemote = NULL;
- tableSize = 0;
- getExtendedUdpTable(NULL, &tableSize, FALSE,
- AF_INET6, UDP_TABLE_OWNER_PID, 0);
-
- table = malloc(tableSize);
- if (table == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6,
- UDP_TABLE_OWNER_PID, 0) == 0)
- {
- udp6Table = table;
-
- for (i = 0; i < udp6Table->dwNumEntries; i++)
- {
- if (pid != -1) {
- if (udp6Table->table[i].dwOwningPid != pid) {
- continue;
- }
- }
-
- if (memcmp(udp6Table->table[i].ucLocalAddr, null_address, 16)
- != 0 || udp6Table->table[i].dwLocalPort != 0)
- {
- struct in6_addr addr;
-
- memcpy(&addr, udp6Table->table[i].ucLocalAddr, 16);
- rtlIpv6AddressToStringA(&addr, addressBufferLocal);
- addressTupleLocal = Py_BuildValue(
- "(si)",
- addressBufferLocal,
- BYTESWAP_USHORT(udp6Table->table[i].dwLocalPort));
- }
- else {
- addressTupleLocal = PyTuple_New(0);
- }
-
- if (addressTupleLocal == NULL)
- goto error;
-
- connectionTuple = Py_BuildValue(
- "(iiiNNiI)",
- -1,
- AF_INET6,
- SOCK_DGRAM,
- addressTupleLocal,
- PyTuple_New(0),
- PSUTIL_CONN_NONE,
- udp6Table->table[i].dwOwningPid);
- if (!connectionTuple)
- goto error;
- if (PyList_Append(connectionsList, connectionTuple))
- goto error;
- Py_DECREF(connectionTuple);
- }
- }
-
- free(table);
- }
-
- _psutil_conn_decref_objs();
- return connectionsList;
-
-error:
- _psutil_conn_decref_objs();
- Py_XDECREF(connectionTuple);
- Py_XDECREF(addressTupleLocal);
- Py_XDECREF(addressTupleRemote);
- Py_DECREF(connectionsList);
- if (table != NULL)
- free(table);
- return NULL;
-}
-
-
-/*
- * Get process priority as a Python integer.
- */
-static PyObject *
-psutil_proc_priority_get(PyObject *self, PyObject *args)
-{
- long pid;
- DWORD priority;
- HANDLE hProcess;
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
-
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL) {
- return NULL;
- }
-
- priority = GetPriorityClass(hProcess);
- CloseHandle(hProcess);
- if (priority == 0) {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- return Py_BuildValue("i", priority);
-}
-
-
-/*
- * Set process priority.
- */
-static PyObject *
-psutil_proc_priority_set(PyObject *self, PyObject *args)
-{
- long pid;
- int priority;
- int retval;
- HANDLE hProcess;
- DWORD dwDesiredAccess = \
- PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
- if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
- return NULL;
- }
-
- hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
- if (hProcess == NULL) {
- return NULL;
- }
-
- retval = SetPriorityClass(hProcess, priority);
- CloseHandle(hProcess);
- if (retval == 0) {
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-
-#if (_WIN32_WINNT >= 0x0600) // Windows Vista
-/*
- * Get process IO priority as a Python integer.
- */
-static PyObject *
-psutil_proc_io_priority_get(PyObject *self, PyObject *args)
-{
- long pid;
- HANDLE hProcess;
- PULONG IoPriority;
-
- _NtQueryInformationProcess NtQueryInformationProcess =
- (_NtQueryInformationProcess)GetProcAddress(
- GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL) {
- return NULL;
- }
-
- NtQueryInformationProcess(
- hProcess,
- ProcessIoPriority,
- &IoPriority,
- sizeof(ULONG),
- NULL
- );
- CloseHandle(hProcess);
- return Py_BuildValue("i", IoPriority);
-}
-
-
-/*
- * Set process IO priority.
- */
-static PyObject *
-psutil_proc_io_priority_set(PyObject *self, PyObject *args)
-{
- long pid;
- int prio;
- HANDLE hProcess;
-
- _NtSetInformationProcess NtSetInformationProcess =
- (_NtSetInformationProcess)GetProcAddress(
- GetModuleHandleA("ntdll.dll"), "NtSetInformationProcess");
-
- if (NtSetInformationProcess == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "couldn't get NtSetInformationProcess");
- return NULL;
- }
-
- if (! PyArg_ParseTuple(args, "li", &pid, &prio)) {
- return NULL;
- }
- hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_ALL_ACCESS);
- if (hProcess == NULL) {
- return NULL;
- }
-
- NtSetInformationProcess(
- hProcess,
- ProcessIoPriority,
- (PVOID)&prio,
- sizeof((PVOID)prio)
- );
-
- CloseHandle(hProcess);
- Py_RETURN_NONE;
-}
-#endif
-
-
-/*
- * Return a Python tuple referencing process I/O counters.
- */
-static PyObject *
-psutil_proc_io_counters(PyObject *self, PyObject *args)
-{
- DWORD pid;
- HANDLE hProcess;
- IO_COUNTERS IoCounters;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- hProcess = psutil_handle_from_pid(pid);
- if (NULL == hProcess) {
- return NULL;
- }
- if (! GetProcessIoCounters(hProcess, &IoCounters)) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(0);
- }
- CloseHandle(hProcess);
- return Py_BuildValue("(KKKK)",
- IoCounters.ReadOperationCount,
- IoCounters.WriteOperationCount,
- IoCounters.ReadTransferCount,
- IoCounters.WriteTransferCount);
-}
-
-
-/*
- * Return process CPU affinity as a bitmask
- */
-static PyObject *
-psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
-{
- DWORD pid;
- HANDLE hProcess;
- DWORD_PTR proc_mask;
- DWORD_PTR system_mask;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL) {
- return NULL;
- }
- if (GetProcessAffinityMask(hProcess, &proc_mask, &system_mask) == 0) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(0);
- }
-
- CloseHandle(hProcess);
-#ifdef _WIN64
- return Py_BuildValue("K", (unsigned long long)proc_mask);
-#else
- return Py_BuildValue("k", (unsigned long)proc_mask);
-#endif
-}
-
-
-/*
- * Set process CPU affinity
- */
-static PyObject *
-psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
-{
- DWORD pid;
- HANDLE hProcess;
- DWORD dwDesiredAccess = \
- PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
- DWORD_PTR mask;
-
-#ifdef _WIN64
- if (! PyArg_ParseTuple(args, "lK", &pid, &mask))
-#else
- if (! PyArg_ParseTuple(args, "lk", &pid, &mask))
-#endif
- {
- return NULL;
- }
- hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
- if (hProcess == NULL) {
- return NULL;
- }
-
- if (SetProcessAffinityMask(hProcess, mask) == 0) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(0);
- }
-
- CloseHandle(hProcess);
- Py_RETURN_NONE;
-}
-
-
-/*
- * Return True if one of the process threads is in a waiting or
- * suspended status.
- */
-static PyObject *
-psutil_proc_is_suspended(PyObject *self, PyObject *args)
-{
- DWORD pid;
- ULONG i;
- PSYSTEM_PROCESS_INFORMATION process;
- PVOID buffer;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_get_proc_info(pid, &process, &buffer)) {
- return NULL;
- }
- for (i = 0; i < process->NumberOfThreads; i++) {
- if (process->Threads[i].ThreadState != Waiting ||
- process->Threads[i].WaitReason != Suspended)
- {
- free(buffer);
- Py_RETURN_FALSE;
- }
- }
- free(buffer);
- Py_RETURN_TRUE;
-}
-
-
-/*
- * Return path's disk total and free as a Python tuple.
- */
-static PyObject *
-psutil_disk_usage(PyObject *self, PyObject *args)
-{
- BOOL retval;
- ULARGE_INTEGER _, total, free;
- char *path;
-
- if (PyArg_ParseTuple(args, "u", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceExW((LPCWSTR)path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-
- // on Python 2 we also want to accept plain strings other
- // than Unicode
-#if PY_MAJOR_VERSION <= 2
- PyErr_Clear(); // drop the argument parsing error
- if (PyArg_ParseTuple(args, "s", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-#endif
-
- return NULL;
-
-return_:
- if (retval == 0)
- return PyErr_SetFromWindowsErr(0);
- else
- return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
-}
-
-
-/*
- * Return a Python list of named tuples with overall network I/O information
- */
-static PyObject *
-psutil_net_io_counters(PyObject *self, PyObject *args)
-{
- char ifname[MAX_PATH];
- DWORD dwRetVal = 0;
- MIB_IFROW *pIfRow = NULL;
- PIP_ADAPTER_ADDRESSES pAddresses = NULL;
- PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
-
- PyObject *py_retdict = PyDict_New();
- PyObject *py_nic_info = NULL;
- PyObject *py_nic_name = NULL;
-
- if (py_retdict == NULL)
- return NULL;
- pAddresses = psutil_get_nic_addresses();
- if (pAddresses == NULL)
- goto error;
- pCurrAddresses = pAddresses;
-
- while (pCurrAddresses) {
- py_nic_name = NULL;
- py_nic_info = NULL;
- pIfRow = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
-
- if (pIfRow == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- pIfRow->dwIndex = pCurrAddresses->IfIndex;
- dwRetVal = GetIfEntry(pIfRow);
- if (dwRetVal != NO_ERROR) {
- PyErr_SetString(PyExc_RuntimeError, "GetIfEntry() failed.");
- goto error;
- }
-
- py_nic_info = Py_BuildValue("(kkkkkkkk)",
- pIfRow->dwOutOctets,
- pIfRow->dwInOctets,
- pIfRow->dwOutUcastPkts,
- pIfRow->dwInUcastPkts,
- pIfRow->dwInErrors,
- pIfRow->dwOutErrors,
- pIfRow->dwInDiscards,
- pIfRow->dwOutDiscards);
- if (!py_nic_info)
- goto error;
-
- sprintf_s(ifname, MAX_PATH, "%wS", pCurrAddresses->FriendlyName);
- py_nic_name = PyUnicode_Decode(
- ifname, _tcslen(ifname), Py_FileSystemDefaultEncoding, "replace");
-
- if (py_nic_name == NULL)
- goto error;
- if (PyDict_SetItem(py_retdict, py_nic_name, py_nic_info))
- goto error;
- Py_XDECREF(py_nic_name);
- Py_XDECREF(py_nic_info);
-
- free(pIfRow);
- pCurrAddresses = pCurrAddresses->Next;
- }
-
- free(pAddresses);
- return py_retdict;
-
-error:
- Py_XDECREF(py_nic_name);
- Py_XDECREF(py_nic_info);
- Py_DECREF(py_retdict);
- if (pAddresses != NULL)
- free(pAddresses);
- if (pIfRow != NULL)
- free(pIfRow);
- return NULL;
-}
-
-
-/*
- * Return a Python dict of tuples for disk I/O information
- */
-static PyObject *
-psutil_disk_io_counters(PyObject *self, PyObject *args)
-{
- DISK_PERFORMANCE_WIN_2008 diskPerformance;
- DWORD dwSize;
- HANDLE hDevice = NULL;
- char szDevice[MAX_PATH];
- char szDeviceDisplay[MAX_PATH];
- int devNum;
- PyObject *py_retdict = PyDict_New();
- PyObject *py_disk_info = NULL;
- if (py_retdict == NULL) {
- return NULL;
- }
-
- // Apparently there's no way to figure out how many times we have
- // to iterate in order to find valid drives.
- // Let's assume 32, which is higher than 26, the number of letters
- // in the alphabet (from A:\ to Z:\).
- for (devNum = 0; devNum <= 32; ++devNum) {
- py_disk_info = NULL;
- sprintf_s(szDevice, MAX_PATH, "\\\\.\\PhysicalDrive%d", devNum);
- hDevice = CreateFile(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
-
- if (hDevice == INVALID_HANDLE_VALUE) {
- continue;
- }
- if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
- &diskPerformance, sizeof(diskPerformance),
- &dwSize, NULL))
- {
- sprintf_s(szDeviceDisplay, MAX_PATH, "PhysicalDrive%d", devNum);
- py_disk_info = Py_BuildValue(
- "(IILLKK)",
- diskPerformance.ReadCount,
- diskPerformance.WriteCount,
- diskPerformance.BytesRead,
- diskPerformance.BytesWritten,
- (unsigned long long)(diskPerformance.ReadTime.QuadPart * 10) / 1000,
- (unsigned long long)(diskPerformance.WriteTime.QuadPart * 10) / 1000);
- if (!py_disk_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, szDeviceDisplay,
- py_disk_info))
- {
- goto error;
- }
- Py_XDECREF(py_disk_info);
- }
- else {
- // XXX we might get here with ERROR_INSUFFICIENT_BUFFER when
- // compiling with mingw32; not sure what to do.
- // return PyErr_SetFromWindowsErr(0);
- ;;
- }
-
- CloseHandle(hDevice);
- }
-
- return py_retdict;
-
-error:
- Py_XDECREF(py_disk_info);
- Py_DECREF(py_retdict);
- if (hDevice != NULL)
- CloseHandle(hDevice);
- return NULL;
-}
-
-
-static char *psutil_get_drive_type(int type)
-{
- switch (type) {
- case DRIVE_FIXED:
- return "fixed";
- case DRIVE_CDROM:
- return "cdrom";
- case DRIVE_REMOVABLE:
- return "removable";
- case DRIVE_UNKNOWN:
- return "unknown";
- case DRIVE_NO_ROOT_DIR:
- return "unmounted";
- case DRIVE_REMOTE:
- return "remote";
- case DRIVE_RAMDISK:
- return "ramdisk";
- default:
- return "?";
- }
-}
-
-
-#ifndef _ARRAYSIZE
-#define _ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
-#endif
-
-/*
- * Return disk partitions as a list of tuples such as
- * (drive_letter, drive_letter, type, "")
- */
-static PyObject *
-psutil_disk_partitions(PyObject *self, PyObject *args)
-{
- DWORD num_bytes;
- char drive_strings[255];
- char *drive_letter = drive_strings;
- int all;
- int type;
- int ret;
- char opts[20];
- LPTSTR fs_type[MAX_PATH + 1] = { 0 };
- DWORD pflags = 0;
- PyObject *py_all;
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_retlist == NULL) {
- return NULL;
- }
-
- // avoid to visualize a message box in case something goes wrong
- // see https://github.com/giampaolo/psutil/issues/264
- SetErrorMode(SEM_FAILCRITICALERRORS);
-
- if (! PyArg_ParseTuple(args, "O", &py_all)) {
- goto error;
- }
- all = PyObject_IsTrue(py_all);
-
- Py_BEGIN_ALLOW_THREADS
- num_bytes = GetLogicalDriveStrings(254, drive_letter);
- Py_END_ALLOW_THREADS
-
- if (num_bytes == 0) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- while (*drive_letter != 0) {
- py_tuple = NULL;
- opts[0] = 0;
- fs_type[0] = 0;
-
- Py_BEGIN_ALLOW_THREADS
- type = GetDriveType(drive_letter);
- Py_END_ALLOW_THREADS
-
- // by default we only show hard drives and cd-roms
- if (all == 0) {
- if ((type == DRIVE_UNKNOWN) ||
- (type == DRIVE_NO_ROOT_DIR) ||
- (type == DRIVE_REMOTE) ||
- (type == DRIVE_RAMDISK)) {
- goto next;
- }
- // floppy disk: skip it by default as it introduces a
- // considerable slowdown.
- if ((type == DRIVE_REMOVABLE) &&
- (strcmp(drive_letter, "A:\\") == 0)) {
- goto next;
- }
- }
-
- ret = GetVolumeInformation(
- (LPCTSTR)drive_letter, NULL, _ARRAYSIZE(drive_letter),
- NULL, NULL, &pflags, (LPTSTR)fs_type, _ARRAYSIZE(fs_type));
- if (ret == 0) {
- // We might get here in case of a floppy hard drive, in
- // which case the error is (21, "device not ready").
- // Let's pretend it didn't happen as we already have
- // the drive name and type ('removable').
- strcat_s(opts, _countof(opts), "");
- SetLastError(0);
- }
- else {
- if (pflags & FILE_READ_ONLY_VOLUME) {
- strcat_s(opts, _countof(opts), "ro");
- }
- else {
- strcat_s(opts, _countof(opts), "rw");
- }
- if (pflags & FILE_VOLUME_IS_COMPRESSED) {
- strcat_s(opts, _countof(opts), ",compressed");
- }
- }
-
- if (strlen(opts) > 0) {
- strcat_s(opts, _countof(opts), ",");
- }
- strcat_s(opts, _countof(opts), psutil_get_drive_type(type));
-
- py_tuple = Py_BuildValue(
- "(ssss)",
- drive_letter,
- drive_letter,
- fs_type, // either FAT, FAT32, NTFS, HPFS, CDFS, UDF or NWFS
- opts);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- goto next;
-
-next:
- drive_letter = strchr(drive_letter, 0) + 1;
- }
-
- SetErrorMode(0);
- return py_retlist;
-
-error:
- SetErrorMode(0);
- Py_XDECREF(py_tuple);
- Py_DECREF(py_retlist);
- return NULL;
-}
-
-/*
- * Return a Python dict of tuples for disk I/O information
- */
-static PyObject *
-psutil_users(PyObject *self, PyObject *args)
-{
- HANDLE hServer = NULL;
- LPTSTR buffer_user = NULL;
- LPTSTR buffer_addr = NULL;
- PWTS_SESSION_INFO sessions = NULL;
- DWORD count;
- DWORD i;
- DWORD sessionId;
- DWORD bytes;
- PWTS_CLIENT_ADDRESS address;
- char address_str[50];
- long long unix_time;
-
- PWINSTATIONQUERYINFORMATIONW WinStationQueryInformationW;
- WINSTATION_INFO station_info;
- HINSTANCE hInstWinSta = NULL;
- ULONG returnLen;
-
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
- PyObject *py_address = NULL;
- PyObject *py_buffer_user_encoded = NULL;
-
- if (py_retlist == NULL) {
- return NULL;
- }
-
- hInstWinSta = LoadLibraryA("winsta.dll");
- WinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW) \
- GetProcAddress(hInstWinSta, "WinStationQueryInformationW");
-
- hServer = WTSOpenServer('\0');
- if (hServer == NULL) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- if (WTSEnumerateSessions(hServer, 0, 1, &sessions, &count) == 0) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- for (i = 0; i < count; i++) {
- py_address = NULL;
- py_tuple = NULL;
- sessionId = sessions[i].SessionId;
- if (buffer_user != NULL) {
- WTSFreeMemory(buffer_user);
- }
- if (buffer_addr != NULL) {
- WTSFreeMemory(buffer_addr);
- }
-
- buffer_user = NULL;
- buffer_addr = NULL;
-
- // username
- bytes = 0;
- if (WTSQuerySessionInformation(hServer, sessionId, WTSUserName,
- &buffer_user, &bytes) == 0) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
- if (bytes == 1) {
- continue;
- }
-
- // address
- bytes = 0;
- if (WTSQuerySessionInformation(hServer, sessionId, WTSClientAddress,
- &buffer_addr, &bytes) == 0) {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- address = (PWTS_CLIENT_ADDRESS)buffer_addr;
- if (address->AddressFamily == 0) { // AF_INET
- sprintf_s(address_str,
- _countof(address_str),
- "%u.%u.%u.%u",
- address->Address[0],
- address->Address[1],
- address->Address[2],
- address->Address[3]);
- py_address = Py_BuildValue("s", address_str);
- if (!py_address)
- goto error;
- }
- else {
- py_address = Py_None;
- }
-
- // login time
- if (!WinStationQueryInformationW(hServer,
- sessionId,
- WinStationInformation,
- &station_info,
- sizeof(station_info),
- &returnLen))
- {
- goto error;
- }
-
- unix_time = ((LONGLONG)station_info.ConnectTime.dwHighDateTime) << 32;
- unix_time += \
- station_info.ConnectTime.dwLowDateTime - 116444736000000000LL;
- unix_time /= 10000000;
-
- py_buffer_user_encoded = PyUnicode_Decode(
- buffer_user, _tcslen(buffer_user), Py_FileSystemDefaultEncoding,
- "replace");
- py_tuple = Py_BuildValue("OOd", py_buffer_user_encoded, py_address,
- (double)unix_time);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_XDECREF(py_buffer_user_encoded);
- Py_XDECREF(py_address);
- Py_XDECREF(py_tuple);
- }
-
- WTSCloseServer(hServer);
- WTSFreeMemory(sessions);
- WTSFreeMemory(buffer_user);
- WTSFreeMemory(buffer_addr);
- FreeLibrary(hInstWinSta);
- return py_retlist;
-
-error:
- Py_XDECREF(py_buffer_user_encoded);
- Py_XDECREF(py_tuple);
- Py_XDECREF(py_address);
- Py_DECREF(py_retlist);
-
- if (hInstWinSta != NULL) {
- FreeLibrary(hInstWinSta);
- }
- if (hServer != NULL) {
- WTSCloseServer(hServer);
- }
- if (sessions != NULL) {
- WTSFreeMemory(sessions);
- }
- if (buffer_user != NULL) {
- WTSFreeMemory(buffer_user);
- }
- if (buffer_addr != NULL) {
- WTSFreeMemory(buffer_addr);
- }
- return NULL;
-}
-
-
-/*
- * Return the number of handles opened by process.
- */
-static PyObject *
-psutil_proc_num_handles(PyObject *self, PyObject *args)
-{
- DWORD pid;
- HANDLE hProcess;
- DWORD handleCount;
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- hProcess = psutil_handle_from_pid(pid);
- if (NULL == hProcess) {
- return NULL;
- }
- if (! GetProcessHandleCount(hProcess, &handleCount)) {
- CloseHandle(hProcess);
- return PyErr_SetFromWindowsErr(0);
- }
- CloseHandle(hProcess);
- return Py_BuildValue("k", handleCount);
-}
-
-
-/*
- * Get various process information by using NtQuerySystemInformation.
- * We use this as a fallback when faster functions fail with access
- * denied. This is slower because it iterates over all processes.
- * Returned tuple includes the following process info:
- *
- * - num_threads
- * - ctx_switches
- * - num_handles (fallback)
- * - user/kernel times (fallback)
- * - create time (fallback)
- * - io counters (fallback)
- */
-static PyObject *
-psutil_proc_info(PyObject *self, PyObject *args)
-{
- DWORD pid;
- PSYSTEM_PROCESS_INFORMATION process;
- PVOID buffer;
- ULONG num_handles;
- ULONG i;
- ULONG ctx_switches = 0;
- double user_time;
- double kernel_time;
- long long create_time;
- int num_threads;
- LONGLONG io_rcount, io_wcount, io_rbytes, io_wbytes;
-
-
- if (! PyArg_ParseTuple(args, "l", &pid))
- return NULL;
- if (! psutil_get_proc_info(pid, &process, &buffer))
- return NULL;
-
- num_handles = process->HandleCount;
- for (i = 0; i < process->NumberOfThreads; i++)
- ctx_switches += process->Threads[i].ContextSwitches;
- user_time = (double)process->UserTime.HighPart * 429.4967296 + \
- (double)process->UserTime.LowPart * 1e-7;
- kernel_time = (double)process->KernelTime.HighPart * 429.4967296 + \
- (double)process->KernelTime.LowPart * 1e-7;
- // Convert the LARGE_INTEGER union to a Unix time.
- // It's the best I could find by googling and borrowing code here
- // and there. The time returned has a precision of 1 second.
- if (0 == pid || 4 == pid) {
- // the python module will translate this into BOOT_TIME later
- create_time = 0;
- }
- else {
- create_time = ((LONGLONG)process->CreateTime.HighPart) << 32;
- create_time += process->CreateTime.LowPart - 116444736000000000LL;
- create_time /= 10000000;
- }
- num_threads = (int)process->NumberOfThreads;
- io_rcount = process->ReadOperationCount.QuadPart;
- io_wcount = process->WriteOperationCount.QuadPart;
- io_rbytes = process->ReadTransferCount.QuadPart;
- io_wbytes = process->WriteTransferCount.QuadPart;
- free(buffer);
-
- return Py_BuildValue(
- "kkdddiKKKK",
- num_handles,
- ctx_switches,
- user_time,
- kernel_time,
- (double)create_time,
- num_threads,
- io_rcount,
- io_wcount,
- io_rbytes,
- io_wbytes
- );
-}
-
-
-static char *get_region_protection_string(ULONG protection)
-{
- switch (protection & 0xff) {
- case PAGE_NOACCESS:
- return "";
- case PAGE_READONLY:
- return "r";
- case PAGE_READWRITE:
- return "rw";
- case PAGE_WRITECOPY:
- return "wc";
- case PAGE_EXECUTE:
- return "x";
- case PAGE_EXECUTE_READ:
- return "xr";
- case PAGE_EXECUTE_READWRITE:
- return "xrw";
- case PAGE_EXECUTE_WRITECOPY:
- return "xwc";
- default:
- return "?";
- }
-}
-
-
-/*
- * Return a list of process's memory mappings.
- */
-static PyObject *
-psutil_proc_memory_maps(PyObject *self, PyObject *args)
-{
- DWORD pid;
- HANDLE hProcess = NULL;
- MEMORY_BASIC_INFORMATION basicInfo;
- PVOID baseAddress;
- PVOID previousAllocationBase;
- CHAR mappedFileName[MAX_PATH];
- SYSTEM_INFO system_info;
- LPVOID maxAddr;
- PyObject *py_list = PyList_New(0);
- PyObject *py_tuple = NULL;
-
- if (py_list == NULL) {
- return NULL;
- }
- if (! PyArg_ParseTuple(args, "l", &pid)) {
- goto error;
- }
- hProcess = psutil_handle_from_pid(pid);
- if (NULL == hProcess) {
- goto error;
- }
-
- GetSystemInfo(&system_info);
- maxAddr = system_info.lpMaximumApplicationAddress;
- baseAddress = NULL;
- previousAllocationBase = NULL;
-
- while (VirtualQueryEx(hProcess, baseAddress, &basicInfo,
- sizeof(MEMORY_BASIC_INFORMATION)))
- {
- py_tuple = NULL;
- if (baseAddress > maxAddr) {
- break;
- }
- if (GetMappedFileNameA(hProcess, baseAddress, mappedFileName,
- sizeof(mappedFileName)))
- {
- py_tuple = Py_BuildValue(
- "(kssI)",
- (unsigned long)baseAddress,
- get_region_protection_string(basicInfo.Protect),
- mappedFileName,
- basicInfo.RegionSize);
- if (!py_tuple)
- goto error;
- if (PyList_Append(py_list, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- }
- previousAllocationBase = basicInfo.AllocationBase;
- baseAddress = (PCHAR)baseAddress + basicInfo.RegionSize;
- }
-
- CloseHandle(hProcess);
- return py_list;
-
-error:
- Py_XDECREF(py_tuple);
- Py_DECREF(py_list);
- if (hProcess != NULL)
- CloseHandle(hProcess);
- return NULL;
-}
-
-
-/*
- * Return a {pid:ppid, ...} dict for all running processes.
- */
-static PyObject *
-psutil_ppid_map(PyObject *self, PyObject *args)
-{
- PyObject *pid = NULL;
- PyObject *ppid = NULL;
- PyObject *py_retdict = PyDict_New();
- HANDLE handle = NULL;
- PROCESSENTRY32 pe = {0};
- pe.dwSize = sizeof(PROCESSENTRY32);
-
- if (py_retdict == NULL)
- return NULL;
- handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (handle == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
- Py_DECREF(py_retdict);
- return NULL;
- }
-
- if (Process32First(handle, &pe)) {
- do {
- pid = Py_BuildValue("I", pe.th32ProcessID);
- if (pid == NULL)
- goto error;
- ppid = Py_BuildValue("I", pe.th32ParentProcessID);
- if (ppid == NULL)
- goto error;
- if (PyDict_SetItem(py_retdict, pid, ppid))
- goto error;
- Py_DECREF(pid);
- Py_DECREF(ppid);
- } while (Process32Next(handle, &pe));
- }
-
- CloseHandle(handle);
- return py_retdict;
-
-error:
- Py_XDECREF(pid);
- Py_XDECREF(ppid);
- Py_DECREF(py_retdict);
- CloseHandle(handle);
- return NULL;
-}
-
-
-/*
- * Return NICs addresses.
- */
-
-static PyObject *
-psutil_net_if_addrs(PyObject *self, PyObject *args)
-{
- unsigned int i = 0;
- ULONG family;
- PCTSTR intRet;
- char *ptr;
- char buff[100];
- char ifname[MAX_PATH];
- DWORD bufflen = 100;
- PIP_ADAPTER_ADDRESSES pAddresses = NULL;
- PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
- PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
-
- PyObject *py_retlist = PyList_New(0);
- PyObject *py_tuple = NULL;
- PyObject *py_address = NULL;
- PyObject *py_mac_address = NULL;
-
- if (py_retlist == NULL)
- return NULL;
-
- pAddresses = psutil_get_nic_addresses();
- if (pAddresses == NULL)
- goto error;
- pCurrAddresses = pAddresses;
-
- while (pCurrAddresses) {
- pUnicast = pCurrAddresses->FirstUnicastAddress;
- sprintf_s(ifname, MAX_PATH, "%wS", pCurrAddresses->FriendlyName);
-
- // MAC address
- if (pCurrAddresses->PhysicalAddressLength != 0) {
- ptr = buff;
- *ptr = '\0';
- for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength; i++) {
- if (i == (pCurrAddresses->PhysicalAddressLength - 1)) {
- sprintf_s(ptr, _countof(buff), "%.2X\n",
- (int)pCurrAddresses->PhysicalAddress[i]);
- }
- else {
- sprintf_s(ptr, _countof(buff), "%.2X-",
- (int)pCurrAddresses->PhysicalAddress[i]);
- }
- ptr += 3;
- }
- *--ptr = '\0';
-
-#if PY_MAJOR_VERSION >= 3
- py_mac_address = PyUnicode_FromString(buff);
-#else
- py_mac_address = PyString_FromString(buff);
-#endif
- if (py_mac_address == NULL)
- goto error;
-
- Py_INCREF(Py_None);
- Py_INCREF(Py_None);
- py_tuple = Py_BuildValue(
- "(siOOO)",
- ifname,
- -1, // this will be converted later to AF_LINK
- py_mac_address,
- Py_None,
- Py_None
- );
- if (! py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- Py_DECREF(py_mac_address);
- }
-
- // find out the IP address associated with the NIC
- if (pUnicast != NULL) {
- for (i = 0; pUnicast != NULL; i++) {
- family = pUnicast->Address.lpSockaddr->sa_family;
- if (family == AF_INET) {
- struct sockaddr_in *sa_in = (struct sockaddr_in *)
- pUnicast->Address.lpSockaddr;
- intRet = inet_ntop(AF_INET, &(sa_in->sin_addr), buff,
- bufflen);
- }
- else if (family == AF_INET6) {
- struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)
- pUnicast->Address.lpSockaddr;
- intRet = inet_ntop(AF_INET6, &(sa_in6->sin6_addr),
- buff, bufflen);
- }
- else {
- // we should never get here
- pUnicast = pUnicast->Next;
- continue;
- }
-
- if (intRet == NULL) {
- PyErr_SetFromWindowsErr(GetLastError());
- goto error;
- }
-#if PY_MAJOR_VERSION >= 3
- py_address = PyUnicode_FromString(buff);
-#else
- py_address = PyString_FromString(buff);
-#endif
- if (py_address == NULL)
- goto error;
-
- Py_INCREF(Py_None);
- Py_INCREF(Py_None);
- py_tuple = Py_BuildValue(
- "(siOOO)",
- ifname,
- family,
- py_address,
- Py_None,
- Py_None
- );
-
- if (! py_tuple)
- goto error;
- if (PyList_Append(py_retlist, py_tuple))
- goto error;
- Py_DECREF(py_tuple);
- Py_DECREF(py_address);
-
- pUnicast = pUnicast->Next;
- }
- }
-
- pCurrAddresses = pCurrAddresses->Next;
- }
-
- free(pAddresses);
- return py_retlist;
-
-error:
- if (pAddresses)
- free(pAddresses);
- Py_DECREF(py_retlist);
- Py_XDECREF(py_tuple);
- Py_XDECREF(py_address);
- return NULL;
-}
-
-
-/*
- * Provides stats about NIC interfaces installed on the system.
- * TODO: get 'duplex' (currently it's hard coded to '2', aka
- 'full duplex')
- */
-static PyObject *
-psutil_net_if_stats(PyObject *self, PyObject *args)
-{
- int i;
- DWORD dwSize = 0;
- DWORD dwRetVal = 0;
- MIB_IFTABLE *pIfTable;
- MIB_IFROW *pIfRow;
- PIP_ADAPTER_ADDRESSES pAddresses = NULL;
- PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
- char friendly_name[MAX_PATH];
- char descr[MAX_PATH];
- int ifname_found;
-
- PyObject *py_retdict = PyDict_New();
- PyObject *py_ifc_info = NULL;
- PyObject *py_is_up = NULL;
-
- if (py_retdict == NULL)
- return NULL;
-
- pAddresses = psutil_get_nic_addresses();
- if (pAddresses == NULL)
- goto error;
-
- pIfTable = (MIB_IFTABLE *) malloc(sizeof (MIB_IFTABLE));
- if (pIfTable == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- dwSize = sizeof(MIB_IFTABLE);
- if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
- free(pIfTable);
- pIfTable = (MIB_IFTABLE *) malloc(dwSize);
- if (pIfTable == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- }
- // Make a second call to GetIfTable to get the actual
- // data we want.
- if ((dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE)) != NO_ERROR) {
- PyErr_SetString(PyExc_RuntimeError, "GetIfTable() failed");
- goto error;
- }
-
- for (i = 0; i < (int) pIfTable->dwNumEntries; i++) {
- pIfRow = (MIB_IFROW *) & pIfTable->table[i];
-
- // GetIfTable is not able to give us NIC with "friendly names"
- // so we determine them via GetAdapterAddresses() which
- // provides friendly names *and* descriptions and find the
- // ones that match.
- ifname_found = 0;
- pCurrAddresses = pAddresses;
- while (pCurrAddresses) {
- sprintf_s(descr, MAX_PATH, "%wS", pCurrAddresses->Description);
- if (lstrcmp(descr, pIfRow->bDescr) == 0) {
- sprintf_s(friendly_name, MAX_PATH, "%wS", pCurrAddresses->FriendlyName);
- ifname_found = 1;
- break;
- }
- pCurrAddresses = pCurrAddresses->Next;
- }
- if (ifname_found == 0) {
- // Name not found means GetAdapterAddresses() doesn't list
- // this NIC, only GetIfTable, meaning it's not really a NIC
- // interface so we skip it.
- continue;
- }
-
- // is up?
- if((pIfRow->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
- pIfRow->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) &&
- pIfRow->dwAdminStatus == 1 ) {
- py_is_up = Py_True;
- }
- else {
- py_is_up = Py_False;
- }
- Py_INCREF(py_is_up);
-
- py_ifc_info = Py_BuildValue(
- "(Oikk)",
- py_is_up,
- 2, // there's no way to know duplex so let's assume 'full'
- pIfRow->dwSpeed / 1000000, // expressed in bytes, we want Mb
- pIfRow->dwMtu
- );
- if (!py_ifc_info)
- goto error;
- if (PyDict_SetItemString(py_retdict, friendly_name, py_ifc_info))
- goto error;
- Py_DECREF(py_ifc_info);
- }
-
- free(pIfTable);
- free(pAddresses);
- return py_retdict;
-
-error:
- Py_XDECREF(py_is_up);
- Py_XDECREF(py_ifc_info);
- Py_DECREF(py_retdict);
- if (pIfTable != NULL)
- free(pIfTable);
- if (pAddresses != NULL)
- free(pAddresses);
- return NULL;
-}
-
-
-// ------------------------ Python init ---------------------------
-
-static PyMethodDef
-PsutilMethods[] =
-{
- // --- per-process functions
-
- {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
- "Return process cmdline as a list of cmdline arguments"},
- {"proc_exe", psutil_proc_exe, METH_VARARGS,
- "Return path of the process executable"},
- {"proc_name", psutil_proc_name, METH_VARARGS,
- "Return process name"},
- {"proc_kill", psutil_proc_kill, METH_VARARGS,
- "Kill the process identified by the given PID"},
- {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
- "Return tuple of user/kern time for the given PID"},
- {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
- "Return a float indicating the process create time expressed in "
- "seconds since the epoch"},
- {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
- "Return a tuple of process memory information"},
- {"proc_memory_info_2", psutil_proc_memory_info_2, METH_VARARGS,
- "Alternate implementation"},
- {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
- "Return process current working directory"},
- {"proc_suspend", psutil_proc_suspend, METH_VARARGS,
- "Suspend a process"},
- {"proc_resume", psutil_proc_resume, METH_VARARGS,
- "Resume a process"},
- {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
- "Return files opened by process"},
- {"proc_username", psutil_proc_username, METH_VARARGS,
- "Return the username of a process"},
- {"proc_threads", psutil_proc_threads, METH_VARARGS,
- "Return process threads information as a list of tuple"},
- {"proc_wait", psutil_proc_wait, METH_VARARGS,
- "Wait for process to terminate and return its exit code."},
- {"proc_priority_get", psutil_proc_priority_get, METH_VARARGS,
- "Return process priority."},
- {"proc_priority_set", psutil_proc_priority_set, METH_VARARGS,
- "Set process priority."},
-#if (_WIN32_WINNT >= 0x0600) // Windows Vista
- {"proc_io_priority_get", psutil_proc_io_priority_get, METH_VARARGS,
- "Return process IO priority."},
- {"proc_io_priority_set", psutil_proc_io_priority_set, METH_VARARGS,
- "Set process IO priority."},
-#endif
- {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
- "Return process CPU affinity as a bitmask."},
- {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
- "Set process CPU affinity."},
- {"proc_io_counters", psutil_proc_io_counters, METH_VARARGS,
- "Get process I/O counters."},
- {"proc_is_suspended", psutil_proc_is_suspended, METH_VARARGS,
- "Return True if one of the process threads is in a suspended state"},
- {"proc_num_handles", psutil_proc_num_handles, METH_VARARGS,
- "Return the number of handles opened by process."},
- {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
- "Return a list of process's memory mappings"},
-
- // --- alternative pinfo interface
- {"proc_info", psutil_proc_info, METH_VARARGS,
- "Various process information"},
-
- // --- system-related functions
- {"pids", psutil_pids, METH_VARARGS,
- "Returns a list of PIDs currently running on the system"},
- {"ppid_map", psutil_ppid_map, METH_VARARGS,
- "Return a {pid:ppid, ...} dict for all running processes"},
- {"pid_exists", psutil_pid_exists, METH_VARARGS,
- "Determine if the process exists in the current process list."},
- {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
- "Returns the number of logical CPUs on the system"},
- {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
- "Returns the number of physical CPUs on the system"},
- {"boot_time", psutil_boot_time, METH_VARARGS,
- "Return the system boot time expressed in seconds since the epoch."},
- {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
- "Return the total amount of physical memory, in bytes"},
- {"cpu_times", psutil_cpu_times, METH_VARARGS,
- "Return system cpu times as a list"},
- {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
- "Return system per-cpu times as a list of tuples"},
- {"disk_usage", psutil_disk_usage, METH_VARARGS,
- "Return path's disk total and free as a Python tuple."},
- {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
- "Return dict of tuples of networks I/O information."},
- {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
- "Return dict of tuples of disks I/O information."},
- {"users", psutil_users, METH_VARARGS,
- "Return a list of currently connected users."},
- {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
- "Return disk partitions."},
- {"net_connections", psutil_net_connections, METH_VARARGS,
- "Return system-wide connections"},
- {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
- "Return NICs addresses."},
- {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
- "Return NICs stats."},
-
- // --- windows API bindings
- {"win32_QueryDosDevice", psutil_win32_QueryDosDevice, METH_VARARGS,
- "QueryDosDevice binding"},
-
- {NULL, NULL, 0, NULL}
-};
-
-
-struct module_state {
- PyObject *error;
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-static struct module_state _state;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static int psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(GETSTATE(m)->error);
- return 0;
-}
-
-static int psutil_windows_clear(PyObject *m) {
- Py_CLEAR(GETSTATE(m)->error);
- return 0;
-}
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "psutil_windows",
- NULL,
- sizeof(struct module_state),
- PsutilMethods,
- NULL,
- psutil_windows_traverse,
- psutil_windows_clear,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_windows(void)
-
-#else
-#define INITERROR return
-void init_psutil_windows(void)
-#endif
-{
- struct module_state *st = NULL;
-#if PY_MAJOR_VERSION >= 3
- PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_windows", PsutilMethods);
-#endif
-
- if (module == NULL) {
- INITERROR;
- }
-
- st = GETSTATE(module);
- st->error = PyErr_NewException("_psutil_windows.Error", NULL, NULL);
- if (st->error == NULL) {
- Py_DECREF(module);
- INITERROR;
- }
-
- PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
-
- // process status constants
- // http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx
- PyModule_AddIntConstant(
- module, "ABOVE_NORMAL_PRIORITY_CLASS", ABOVE_NORMAL_PRIORITY_CLASS);
- PyModule_AddIntConstant(
- module, "BELOW_NORMAL_PRIORITY_CLASS", BELOW_NORMAL_PRIORITY_CLASS);
- PyModule_AddIntConstant(
- module, "HIGH_PRIORITY_CLASS", HIGH_PRIORITY_CLASS);
- PyModule_AddIntConstant(
- module, "IDLE_PRIORITY_CLASS", IDLE_PRIORITY_CLASS);
- PyModule_AddIntConstant(
- module, "NORMAL_PRIORITY_CLASS", NORMAL_PRIORITY_CLASS);
- PyModule_AddIntConstant(
- module, "REALTIME_PRIORITY_CLASS", REALTIME_PRIORITY_CLASS);
- // connection status constants
- // http://msdn.microsoft.com/en-us/library/cc669305.aspx
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_CLOSED", MIB_TCP_STATE_CLOSED);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_CLOSING", MIB_TCP_STATE_CLOSING);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_CLOSE_WAIT", MIB_TCP_STATE_CLOSE_WAIT);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_LISTEN", MIB_TCP_STATE_LISTEN);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_ESTAB", MIB_TCP_STATE_ESTAB);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_SYN_SENT", MIB_TCP_STATE_SYN_SENT);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_SYN_RCVD", MIB_TCP_STATE_SYN_RCVD);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_FIN_WAIT1", MIB_TCP_STATE_FIN_WAIT1);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_FIN_WAIT2", MIB_TCP_STATE_FIN_WAIT2);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_LAST_ACK", MIB_TCP_STATE_LAST_ACK);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_TIME_WAIT", MIB_TCP_STATE_TIME_WAIT);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_TIME_WAIT", MIB_TCP_STATE_TIME_WAIT);
- PyModule_AddIntConstant(
- module, "MIB_TCP_STATE_DELETE_TCB", MIB_TCP_STATE_DELETE_TCB);
- PyModule_AddIntConstant(
- module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
- // ...for internal use in _psutil_windows.py
- PyModule_AddIntConstant(
- module, "INFINITE", INFINITE);
- PyModule_AddIntConstant(
- module, "ERROR_ACCESS_DENIED", ERROR_ACCESS_DENIED);
-
- // set SeDebug for the current process
- psutil_set_se_debug();
-
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/python/psutil/psutil/_psutil_windows.h b/python/psutil/psutil/_psutil_windows.h
deleted file mode 100644
index c77f64e9c..000000000
--- a/python/psutil/psutil/_psutil_windows.h
+++ /dev/null
@@ -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);
diff --git a/python/psutil/psutil/_pswindows.py b/python/psutil/psutil/_pswindows.py
deleted file mode 100644
index 2d8babb19..000000000
--- a/python/psutil/psutil/_pswindows.py
+++ /dev/null
@@ -1,548 +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.
-
-"""Windows platform implementation."""
-
-import errno
-import functools
-import os
-import sys
-from collections import namedtuple
-
-from . import _common
-from . import _psutil_windows as cext
-from ._common import conn_tmap, usage_percent, isfile_strict
-from ._common import sockfam_to_enum, socktype_to_enum
-from ._compat import PY3, xrange, lru_cache, long
-from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS,
- BELOW_NORMAL_PRIORITY_CLASS,
- HIGH_PRIORITY_CLASS,
- IDLE_PRIORITY_CLASS,
- NORMAL_PRIORITY_CLASS,
- REALTIME_PRIORITY_CLASS)
-
-if sys.version_info >= (3, 4):
- import enum
-else:
- enum = None
-
-# process priority constants, import from __init__.py:
-# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
-__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
- "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
- "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
- "CONN_DELETE_TCB",
- "AF_LINK",
- ]
-
-# --- module level constants (gets pushed up to psutil module)
-
-CONN_DELETE_TCB = "DELETE_TCB"
-WAIT_TIMEOUT = 0x00000102 # 258 in decimal
-ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES,
- cext.ERROR_ACCESS_DENIED])
-if enum is None:
- AF_LINK = -1
-else:
- AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
- AF_LINK = AddressFamily.AF_LINK
-
-TCP_STATUSES = {
- cext.MIB_TCP_STATE_ESTAB: _common.CONN_ESTABLISHED,
- cext.MIB_TCP_STATE_SYN_SENT: _common.CONN_SYN_SENT,
- cext.MIB_TCP_STATE_SYN_RCVD: _common.CONN_SYN_RECV,
- cext.MIB_TCP_STATE_FIN_WAIT1: _common.CONN_FIN_WAIT1,
- cext.MIB_TCP_STATE_FIN_WAIT2: _common.CONN_FIN_WAIT2,
- cext.MIB_TCP_STATE_TIME_WAIT: _common.CONN_TIME_WAIT,
- cext.MIB_TCP_STATE_CLOSED: _common.CONN_CLOSE,
- cext.MIB_TCP_STATE_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
- cext.MIB_TCP_STATE_LAST_ACK: _common.CONN_LAST_ACK,
- cext.MIB_TCP_STATE_LISTEN: _common.CONN_LISTEN,
- cext.MIB_TCP_STATE_CLOSING: _common.CONN_CLOSING,
- cext.MIB_TCP_STATE_DELETE_TCB: CONN_DELETE_TCB,
- cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
-}
-
-if enum is not None:
- class Priority(enum.IntEnum):
- ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
- BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
- HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
- IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
- NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
- REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
-
- globals().update(Priority.__members__)
-
-scputimes = namedtuple('scputimes', ['user', 'system', 'idle'])
-svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
-pextmem = namedtuple(
- 'pextmem', ['num_page_faults', 'peak_wset', 'wset', 'peak_paged_pool',
- 'paged_pool', 'peak_nonpaged_pool', 'nonpaged_pool',
- 'pagefile', 'peak_pagefile', 'private'])
-pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss'])
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-ntpinfo = namedtuple(
- 'ntpinfo', ['num_handles', 'ctx_switches', 'user_time', 'kernel_time',
- 'create_time', 'num_threads', 'io_rcount', 'io_wcount',
- 'io_rbytes', 'io_wbytes'])
-
-# set later from __init__.py
-NoSuchProcess = None
-AccessDenied = None
-TimeoutExpired = None
-
-
-@lru_cache(maxsize=512)
-def _win32_QueryDosDevice(s):
- return cext.win32_QueryDosDevice(s)
-
-
-def _convert_raw_path(s):
- # convert paths using native DOS format like:
- # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
- # into: "C:\Windows\systemew\file.txt"
- if PY3 and not isinstance(s, str):
- s = s.decode('utf8')
- rawdrive = '\\'.join(s.split('\\')[:3])
- driveletter = _win32_QueryDosDevice(rawdrive)
- return os.path.join(driveletter, s[len(rawdrive):])
-
-
-# --- public functions
-
-
-def virtual_memory():
- """System virtual memory as a namedtuple."""
- mem = cext.virtual_mem()
- totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
- #
- total = totphys
- avail = availphys
- free = availphys
- used = total - avail
- percent = usage_percent((total - avail), total, _round=1)
- return svmem(total, avail, percent, used, free)
-
-
-def swap_memory():
- """Swap system memory as a (total, used, free, sin, sout) tuple."""
- mem = cext.virtual_mem()
- total = mem[2]
- free = mem[3]
- used = total - free
- percent = usage_percent(used, total, _round=1)
- return _common.sswap(total, used, free, percent, 0, 0)
-
-
-def disk_usage(path):
- """Return disk usage associated with path."""
- try:
- total, free = cext.disk_usage(path)
- except WindowsError:
- if not os.path.exists(path):
- msg = "No such file or directory: '%s'" % path
- raise OSError(errno.ENOENT, msg)
- raise
- used = total - free
- percent = usage_percent(used, total, _round=1)
- return _common.sdiskusage(total, used, free, percent)
-
-
-def disk_partitions(all):
- """Return disk partitions."""
- rawlist = cext.disk_partitions(all)
- return [_common.sdiskpart(*x) for x in rawlist]
-
-
-def cpu_times():
- """Return system CPU times as a named tuple."""
- user, system, idle = cext.cpu_times()
- return scputimes(user, system, idle)
-
-
-def per_cpu_times():
- """Return system per-CPU times as a list of named tuples."""
- ret = []
- for cpu_t in cext.per_cpu_times():
- user, system, idle = cpu_t
- item = scputimes(user, system, idle)
- ret.append(item)
- return ret
-
-
-def cpu_count_logical():
- """Return the number of logical CPUs in the system."""
- return cext.cpu_count_logical()
-
-
-def cpu_count_physical():
- """Return the number of physical CPUs in the system."""
- return cext.cpu_count_phys()
-
-
-def boot_time():
- """The system boot time expressed in seconds since the epoch."""
- return cext.boot_time()
-
-
-def net_connections(kind, _pid=-1):
- """Return socket connections. If pid == -1 return system-wide
- connections (as opposed to connections opened by one process only).
- """
- if kind not in conn_tmap:
- raise ValueError("invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap])))
- families, types = conn_tmap[kind]
- rawlist = cext.net_connections(_pid, families, types)
- ret = set()
- for item in rawlist:
- fd, fam, type, laddr, raddr, status, pid = item
- status = TCP_STATUSES[status]
- fam = sockfam_to_enum(fam)
- type = socktype_to_enum(type)
- if _pid == -1:
- nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid)
- else:
- nt = _common.pconn(fd, fam, type, laddr, raddr, status)
- ret.add(nt)
- return list(ret)
-
-
-def net_if_stats():
- ret = cext.net_if_stats()
- for name, items in ret.items():
- isup, duplex, speed, mtu = items
- if hasattr(_common, 'NicDuplex'):
- duplex = _common.NicDuplex(duplex)
- ret[name] = _common.snicstats(isup, duplex, speed, mtu)
- return ret
-
-
-def users():
- """Return currently connected users as a list of namedtuples."""
- retlist = []
- rawlist = cext.users()
- for item in rawlist:
- user, hostname, tstamp = item
- nt = _common.suser(user, None, hostname, tstamp)
- retlist.append(nt)
- return retlist
-
-
-pids = cext.pids
-pid_exists = cext.pid_exists
-net_io_counters = cext.net_io_counters
-disk_io_counters = cext.disk_io_counters
-ppid_map = cext.ppid_map # not meant to be public
-net_if_addrs = cext.net_if_addrs
-
-
-def wrap_exceptions(fun):
- """Decorator which translates bare OSError and WindowsError
- exceptions into NoSuchProcess and AccessDenied.
- """
- @functools.wraps(fun)
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except OSError as err:
- # support for private module import
- if NoSuchProcess is None or AccessDenied is None:
- raise
- if err.errno in ACCESS_DENIED_SET:
- raise AccessDenied(self.pid, self._name)
- if err.errno == errno.ESRCH:
- raise NoSuchProcess(self.pid, self._name)
- raise
- return wrapper
-
-
-class Process(object):
- """Wrapper class around underlying C implementation."""
-
- __slots__ = ["pid", "_name", "_ppid"]
-
- def __init__(self, pid):
- self.pid = pid
- self._name = None
- self._ppid = None
-
- @wrap_exceptions
- def name(self):
- """Return process name, which on Windows is always the final
- part of the executable.
- """
- # This is how PIDs 0 and 4 are always represented in taskmgr
- # and process-hacker.
- if self.pid == 0:
- return "System Idle Process"
- elif self.pid == 4:
- return "System"
- else:
- try:
- # Note: this will fail with AD for most PIDs owned
- # by another user but it's faster.
- return os.path.basename(self.exe())
- except AccessDenied:
- return cext.proc_name(self.pid)
-
- @wrap_exceptions
- def exe(self):
- # Note: os.path.exists(path) may return False even if the file
- # is there, see:
- # http://stackoverflow.com/questions/3112546/os-path-exists-lies
-
- # see https://github.com/giampaolo/psutil/issues/414
- # see https://github.com/giampaolo/psutil/issues/528
- if self.pid in (0, 4):
- raise AccessDenied(self.pid, self._name)
- return _convert_raw_path(cext.proc_exe(self.pid))
-
- @wrap_exceptions
- def cmdline(self):
- return cext.proc_cmdline(self.pid)
-
- def ppid(self):
- try:
- return ppid_map()[self.pid]
- except KeyError:
- raise NoSuchProcess(self.pid, self._name)
-
- def _get_raw_meminfo(self):
- try:
- return cext.proc_memory_info(self.pid)
- except OSError as err:
- if err.errno in ACCESS_DENIED_SET:
- # TODO: the C ext can probably be refactored in order
- # to get this from cext.proc_info()
- return cext.proc_memory_info_2(self.pid)
- raise
-
- @wrap_exceptions
- def memory_info(self):
- # on Windows RSS == WorkingSetSize and VSM == PagefileUsage
- # fields of PROCESS_MEMORY_COUNTERS struct:
- # http://msdn.microsoft.com/en-us/library/windows/desktop/
- # ms684877(v=vs.85).aspx
- t = self._get_raw_meminfo()
- return _common.pmem(t[2], t[7])
-
- @wrap_exceptions
- def memory_info_ex(self):
- return pextmem(*self._get_raw_meminfo())
-
- def memory_maps(self):
- try:
- raw = cext.proc_memory_maps(self.pid)
- except OSError as err:
- # XXX - can't use wrap_exceptions decorator as we're
- # returning a generator; probably needs refactoring.
- if err.errno in ACCESS_DENIED_SET:
- raise AccessDenied(self.pid, self._name)
- if err.errno == errno.ESRCH:
- raise NoSuchProcess(self.pid, self._name)
- raise
- else:
- for addr, perm, path, rss in raw:
- path = _convert_raw_path(path)
- addr = hex(addr)
- yield (addr, perm, path, rss)
-
- @wrap_exceptions
- def kill(self):
- return cext.proc_kill(self.pid)
-
- @wrap_exceptions
- def wait(self, timeout=None):
- if timeout is None:
- timeout = cext.INFINITE
- else:
- # WaitForSingleObject() expects time in milliseconds
- timeout = int(timeout * 1000)
- ret = cext.proc_wait(self.pid, timeout)
- if ret == WAIT_TIMEOUT:
- # support for private module import
- if TimeoutExpired is None:
- raise RuntimeError("timeout expired")
- raise TimeoutExpired(timeout, self.pid, self._name)
- return ret
-
- @wrap_exceptions
- def username(self):
- if self.pid in (0, 4):
- return 'NT AUTHORITY\\SYSTEM'
- return cext.proc_username(self.pid)
-
- @wrap_exceptions
- def create_time(self):
- # special case for kernel process PIDs; return system boot time
- if self.pid in (0, 4):
- return boot_time()
- try:
- return cext.proc_create_time(self.pid)
- except OSError as err:
- if err.errno in ACCESS_DENIED_SET:
- return ntpinfo(*cext.proc_info(self.pid)).create_time
- raise
-
- @wrap_exceptions
- def num_threads(self):
- return ntpinfo(*cext.proc_info(self.pid)).num_threads
-
- @wrap_exceptions
- def threads(self):
- rawlist = cext.proc_threads(self.pid)
- retlist = []
- for thread_id, utime, stime in rawlist:
- ntuple = _common.pthread(thread_id, utime, stime)
- retlist.append(ntuple)
- return retlist
-
- @wrap_exceptions
- def cpu_times(self):
- try:
- ret = cext.proc_cpu_times(self.pid)
- except OSError as err:
- if err.errno in ACCESS_DENIED_SET:
- nt = ntpinfo(*cext.proc_info(self.pid))
- ret = (nt.user_time, nt.kernel_time)
- else:
- raise
- return _common.pcputimes(*ret)
-
- @wrap_exceptions
- def suspend(self):
- return cext.proc_suspend(self.pid)
-
- @wrap_exceptions
- def resume(self):
- return cext.proc_resume(self.pid)
-
- @wrap_exceptions
- def cwd(self):
- if self.pid in (0, 4):
- raise AccessDenied(self.pid, self._name)
- # return a normalized pathname since the native C function appends
- # "\\" at the and of the path
- path = cext.proc_cwd(self.pid)
- return os.path.normpath(path)
-
- @wrap_exceptions
- def open_files(self):
- if self.pid in (0, 4):
- return []
- retlist = []
- # Filenames come in in native format like:
- # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
- # Convert the first part in the corresponding drive letter
- # (e.g. "C:\") by using Windows's QueryDosDevice()
- raw_file_names = cext.proc_open_files(self.pid)
- for _file in raw_file_names:
- _file = _convert_raw_path(_file)
- if isfile_strict(_file) and _file not in retlist:
- ntuple = _common.popenfile(_file, -1)
- retlist.append(ntuple)
- return retlist
-
- @wrap_exceptions
- def connections(self, kind='inet'):
- return net_connections(kind, _pid=self.pid)
-
- @wrap_exceptions
- def nice_get(self):
- value = cext.proc_priority_get(self.pid)
- if enum is not None:
- value = Priority(value)
- return value
-
- @wrap_exceptions
- def nice_set(self, value):
- return cext.proc_priority_set(self.pid, value)
-
- # available on Windows >= Vista
- if hasattr(cext, "proc_io_priority_get"):
- @wrap_exceptions
- def ionice_get(self):
- return cext.proc_io_priority_get(self.pid)
-
- @wrap_exceptions
- def ionice_set(self, value, _):
- if _:
- raise TypeError("set_proc_ionice() on Windows takes only "
- "1 argument (2 given)")
- if value not in (2, 1, 0):
- raise ValueError("value must be 2 (normal), 1 (low) or 0 "
- "(very low); got %r" % value)
- return cext.proc_io_priority_set(self.pid, value)
-
- @wrap_exceptions
- def io_counters(self):
- try:
- ret = cext.proc_io_counters(self.pid)
- except OSError as err:
- if err.errno in ACCESS_DENIED_SET:
- nt = ntpinfo(*cext.proc_info(self.pid))
- ret = (nt.io_rcount, nt.io_wcount, nt.io_rbytes, nt.io_wbytes)
- else:
- raise
- return _common.pio(*ret)
-
- @wrap_exceptions
- def status(self):
- suspended = cext.proc_is_suspended(self.pid)
- if suspended:
- return _common.STATUS_STOPPED
- else:
- return _common.STATUS_RUNNING
-
- @wrap_exceptions
- def cpu_affinity_get(self):
- def from_bitmask(x):
- return [i for i in xrange(64) if (1 << i) & x]
- bitmask = cext.proc_cpu_affinity_get(self.pid)
- return from_bitmask(bitmask)
-
- @wrap_exceptions
- def cpu_affinity_set(self, value):
- def to_bitmask(l):
- if not l:
- raise ValueError("invalid argument %r" % l)
- out = 0
- for b in l:
- out |= 2 ** b
- return out
-
- # SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
- # is returned for an invalid CPU but this seems not to be true,
- # therefore we check CPUs validy beforehand.
- allcpus = list(range(len(per_cpu_times())))
- for cpu in value:
- if cpu not in allcpus:
- if not isinstance(cpu, (int, long)):
- raise TypeError(
- "invalid CPU %r; an integer is required" % cpu)
- else:
- raise ValueError("invalid CPU %r" % cpu)
-
- bitmask = to_bitmask(value)
- cext.proc_cpu_affinity_set(self.pid, bitmask)
-
- @wrap_exceptions
- def num_handles(self):
- try:
- return cext.proc_num_handles(self.pid)
- except OSError as err:
- if err.errno in ACCESS_DENIED_SET:
- return ntpinfo(*cext.proc_info(self.pid)).num_handles
- raise
-
- @wrap_exceptions
- def num_ctx_switches(self):
- ctx_switches = ntpinfo(*cext.proc_info(self.pid)).ctx_switches
- # only voluntary ctx switches are supported
- return _common.pctxsw(ctx_switches, 0)
diff --git a/python/psutil/psutil/arch/bsd/process_info.c b/python/psutil/psutil/arch/bsd/process_info.c
deleted file mode 100644
index 4d7392406..000000000
--- a/python/psutil/psutil/arch/bsd/process_info.c
+++ /dev/null
@@ -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;
-}
-
diff --git a/python/psutil/psutil/arch/bsd/process_info.h b/python/psutil/psutil/arch/bsd/process_info.h
deleted file mode 100644
index 858bd88a5..000000000
--- a/python/psutil/psutil/arch/bsd/process_info.h
+++ /dev/null
@@ -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);
diff --git a/python/psutil/psutil/arch/osx/process_info.c b/python/psutil/psutil/arch/osx/process_info.c
deleted file mode 100644
index b6dd5bb93..000000000
--- a/python/psutil/psutil/arch/osx/process_info.c
+++ /dev/null
@@ -1,281 +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_osx module methods.
- */
-
-
-#include <Python.h>
-#include <assert.h>
-#include <errno.h>
-#include <limits.h> // for INT_MAX
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/sysctl.h>
-#include <libproc.h>
-
-#include "process_info.h"
-#include "../../_psutil_common.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
- * 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(kinfo_proc **procList, size_t *procCount)
-{
- // Declaring mib as const requires use of a cast since the
- // sysctl prototype doesn't include the const modifier.
- static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
- size_t size, size2;
- void *ptr;
- int err, lim = 8; // some limit
-
- assert( procList != NULL);
- assert(*procList == NULL);
- assert(procCount != NULL);
-
- *procCount = 0;
-
- /*
- * We start by calling sysctl with ptr == NULL and size == 0.
- * That will succeed, and set size to the appropriate length.
- * We then allocate a buffer of at least that size and call
- * sysctl with that buffer. If that succeeds, we're done.
- * If that call fails with ENOMEM, we throw the buffer away
- * and try again.
- * Note that the loop calls sysctl with NULL again. This is
- * is necessary because the ENOMEM failure case sets size to
- * the amount of data returned, not the amount of data that
- * could have been returned.
- */
- while (lim-- > 0) {
- size = 0;
- if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1)
- return errno;
- size2 = size + (size >> 3); // add some
- if (size2 > size) {
- ptr = malloc(size2);
- if (ptr == NULL)
- ptr = malloc(size);
- else
- size = size2;
- }
- else {
- ptr = malloc(size);
- }
- if (ptr == NULL)
- return ENOMEM;
-
- if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) {
- err = errno;
- free(ptr);
- if (err != ENOMEM)
- return err;
- }
- else {
- *procList = (kinfo_proc *)ptr;
- *procCount = size / sizeof(kinfo_proc);
- return 0;
- }
- }
- return ENOMEM;
-}
-
-
-// Read the maximum argument size for processes
-int
-psutil_get_argmax()
-{
- int argmax;
- int mib[] = { CTL_KERN, KERN_ARGMAX };
- size_t size = sizeof(argmax);
-
- if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0)
- return argmax;
- return 0;
-}
-
-
-// return process args as a python list
-PyObject *
-psutil_get_arg_list(long pid)
-{
- int mib[3];
- int nargs;
- int len;
- char *procargs = NULL;
- char *arg_ptr;
- char *arg_end;
- char *curr_arg;
- size_t argmax;
- PyObject *arg = NULL;
- PyObject *arglist = NULL;
-
- // special case for PID 0 (kernel_task) where cmdline cannot be fetched
- if (pid == 0)
- return Py_BuildValue("[]");
-
- // read argmax and allocate memory for argument space.
- argmax = 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;
- if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
- if (EINVAL == errno) {
- // EINVAL == access denied OR nonexistent PID
- if (psutil_pid_exists(pid))
- AccessDenied();
- else
- NoSuchProcess();
- }
- goto error;
- }
-
- arg_end = &procargs[argmax];
- // copy the number of arguments to nargs
- memcpy(&nargs, procargs, sizeof(nargs));
-
- arg_ptr = procargs + sizeof(nargs);
- len = strlen(arg_ptr);
- arg_ptr += len + 1;
-
- if (arg_ptr == arg_end) {
- free(procargs);
- return Py_BuildValue("[]");
- }
-
- // skip ahead to the first argument
- for (; arg_ptr < arg_end; arg_ptr++) {
- if (*arg_ptr != '\0')
- break;
- }
-
- // iterate through arguments
- curr_arg = arg_ptr;
- arglist = Py_BuildValue("[]");
- if (!arglist)
- goto error;
- while (arg_ptr < arg_end && nargs > 0) {
- if (*arg_ptr++ == '\0') {
- arg = Py_BuildValue("s", curr_arg);
- if (!arg)
- goto error;
- if (PyList_Append(arglist, arg))
- goto error;
- Py_DECREF(arg);
- // iterate to next arg and decrement # of args
- curr_arg = arg_ptr;
- nargs--;
- }
- }
-
- free(procargs);
- return arglist;
-
-error:
- Py_XDECREF(arg);
- Py_XDECREF(arglist);
- if (procargs != NULL)
- free(procargs);
- return NULL;
-}
-
-
-int
-psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
-{
- int mib[4];
- size_t len;
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = pid;
-
- // fetch the info with sysctl()
- len = sizeof(struct kinfo_proc);
-
- // now read the data from sysctl
- if (sysctl(mib, 4, kp, &len, NULL, 0) == -1) {
- // raise an exception and throw errno as the error
- PyErr_SetFromErrno(PyExc_OSError);
- return -1;
- }
-
- // sysctl succeeds but len is zero, happens when process has gone away
- if (len == 0) {
- NoSuchProcess();
- return -1;
- }
- return 0;
-}
-
-
-/*
- * A thin wrapper around proc_pidinfo()
- */
-int
-psutil_proc_pidinfo(long pid, int flavor, void *pti, int size)
-{
- int ret = proc_pidinfo((int)pid, flavor, 0, pti, size);
- if (ret == 0) {
- if (! psutil_pid_exists(pid)) {
- NoSuchProcess();
- return 0;
- }
- else {
- AccessDenied();
- return 0;
- }
- }
- else if (ret != size) {
- AccessDenied();
- return 0;
- }
- else {
- return 1;
- }
-}
diff --git a/python/psutil/psutil/arch/osx/process_info.h b/python/psutil/psutil/arch/osx/process_info.h
deleted file mode 100644
index c89c8570e..000000000
--- a/python/psutil/psutil/arch/osx/process_info.h
+++ /dev/null
@@ -1,16 +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;
-
-int psutil_get_argmax(void);
-int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
-int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
-int psutil_pid_exists(long pid);
-int psutil_proc_pidinfo(long pid, int flavor, void *pti, int size);
-PyObject* psutil_get_arg_list(long pid);
diff --git a/python/psutil/psutil/arch/windows/glpi.h b/python/psutil/psutil/arch/windows/glpi.h
deleted file mode 100644
index 6f9848373..000000000
--- a/python/psutil/psutil/arch/windows/glpi.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// mingw headers are missing this
-
-typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
- RelationProcessorCore,
- RelationNumaNode,
- RelationCache,
- RelationProcessorPackage,
- RelationGroup,
- RelationAll=0xffff
-} LOGICAL_PROCESSOR_RELATIONSHIP;
-
-typedef enum _PROCESSOR_CACHE_TYPE {
- CacheUnified,CacheInstruction,CacheData,CacheTrace
-} PROCESSOR_CACHE_TYPE;
-
-typedef struct _CACHE_DESCRIPTOR {
- BYTE Level;
- BYTE Associativity;
- WORD LineSize;
- DWORD Size;
- PROCESSOR_CACHE_TYPE Type;
-} CACHE_DESCRIPTOR,*PCACHE_DESCRIPTOR;
-
-typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
- ULONG_PTR ProcessorMask;
- LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
- union {
- struct {
- BYTE Flags;
- } ProcessorCore;
- struct {
- DWORD NodeNumber;
- } NumaNode;
- CACHE_DESCRIPTOR Cache;
- ULONGLONG Reserved[2];
- };
-} SYSTEM_LOGICAL_PROCESSOR_INFORMATION,*PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
-
-WINBASEAPI WINBOOL WINAPI
-GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
- PDWORD ReturnedLength); \ No newline at end of file
diff --git a/python/psutil/psutil/arch/windows/inet_ntop.c b/python/psutil/psutil/arch/windows/inet_ntop.c
deleted file mode 100644
index b9fffd1c1..000000000
--- a/python/psutil/psutil/arch/windows/inet_ntop.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "inet_ntop.h"
-
-// From: https://memset.wordpress.com/2010/10/09/inet_ntop-for-win32/
-PCSTR
-WSAAPI
-inet_ntop(
- __in INT Family,
- __in PVOID pAddr,
- __out_ecount(StringBufSize) PSTR pStringBuf,
- __in size_t StringBufSize
- )
-{
- DWORD dwAddressLength = 0;
- struct sockaddr_storage srcaddr;
- struct sockaddr_in *srcaddr4 = (struct sockaddr_in*) &srcaddr;
- struct sockaddr_in6 *srcaddr6 = (struct sockaddr_in6*) &srcaddr;
-
- memset(&srcaddr, 0, sizeof(struct sockaddr_storage));
- srcaddr.ss_family = Family;
-
- if (Family == AF_INET)
- {
- dwAddressLength = sizeof(struct sockaddr_in);
- memcpy(&(srcaddr4->sin_addr), pAddr, sizeof(struct in_addr));
- } else if (Family == AF_INET6)
- {
- dwAddressLength = sizeof(struct sockaddr_in6);
- memcpy(&(srcaddr6->sin6_addr), pAddr, sizeof(struct in6_addr));
- } else {
- return NULL;
- }
-
- if (WSAAddressToString((LPSOCKADDR) &srcaddr,
- dwAddressLength,
- 0,
- pStringBuf,
- (LPDWORD) &StringBufSize) != 0) {
- return NULL;
- }
- return pStringBuf;
-} \ No newline at end of file
diff --git a/python/psutil/psutil/arch/windows/inet_ntop.h b/python/psutil/psutil/arch/windows/inet_ntop.h
deleted file mode 100644
index 0d97e28c8..000000000
--- a/python/psutil/psutil/arch/windows/inet_ntop.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <ws2tcpip.h>
-
-PCSTR
-WSAAPI
-inet_ntop(
- __in INT Family,
- __in PVOID pAddr,
- __out_ecount(StringBufSize) PSTR pStringBuf,
- __in size_t StringBufSize
-); \ No newline at end of file
diff --git a/python/psutil/psutil/arch/windows/ntextapi.h b/python/psutil/psutil/arch/windows/ntextapi.h
deleted file mode 100644
index d10432a3e..000000000
--- a/python/psutil/psutil/arch/windows/ntextapi.h
+++ /dev/null
@@ -1,228 +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.
- */
-#if !defined(__NTEXTAPI_H__)
-#define __NTEXTAPI_H__
-#include <winternl.h>
-
-typedef enum _KTHREAD_STATE {
- Initialized,
- Ready,
- Running,
- Standby,
- Terminated,
- Waiting,
- Transition,
- DeferredReady,
- GateWait,
- MaximumThreadState
-} KTHREAD_STATE, *PKTHREAD_STATE;
-
-typedef enum _KWAIT_REASON {
- Executive = 0,
- FreePage = 1,
- PageIn = 2,
- PoolAllocation = 3,
- DelayExecution = 4,
- Suspended = 5,
- UserRequest = 6,
- WrExecutive = 7,
- WrFreePage = 8,
- WrPageIn = 9,
- WrPoolAllocation = 10,
- WrDelayExecution = 11,
- WrSuspended = 12,
- WrUserRequest = 13,
- WrEventPair = 14,
- WrQueue = 15,
- WrLpcReceive = 16,
- WrLpcReply = 17,
- WrVirtualMemory = 18,
- WrPageOut = 19,
- WrRendezvous = 20,
- Spare2 = 21,
- Spare3 = 22,
- Spare4 = 23,
- Spare5 = 24,
- WrCalloutStack = 25,
- WrKernel = 26,
- WrResource = 27,
- WrPushLock = 28,
- WrMutex = 29,
- WrQuantumEnd = 30,
- WrDispatchInt = 31,
- WrPreempted = 32,
- WrYieldExecution = 33,
- WrFastMutex = 34,
- WrGuardedMutex = 35,
- WrRundown = 36,
- MaximumWaitReason = 37
-} KWAIT_REASON, *PKWAIT_REASON;
-
-typedef struct _CLIENT_ID {
- HANDLE UniqueProcess;
- HANDLE UniqueThread;
-} CLIENT_ID, *PCLIENT_ID;
-
-typedef struct _SYSTEM_THREAD_INFORMATION {
- LARGE_INTEGER KernelTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER CreateTime;
- ULONG WaitTime;
- PVOID StartAddress;
- CLIENT_ID ClientId;
- LONG Priority;
- LONG BasePriority;
- ULONG ContextSwitches;
- ULONG ThreadState;
- KWAIT_REASON WaitReason;
-} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
-
-typedef struct _TEB *PTEB;
-
-// private
-typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION {
- SYSTEM_THREAD_INFORMATION ThreadInfo;
- PVOID StackBase;
- PVOID StackLimit;
- PVOID Win32StartAddress;
- PTEB TebBase;
- ULONG_PTR Reserved2;
- ULONG_PTR Reserved3;
- ULONG_PTR Reserved4;
-} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
-
-typedef struct _SYSTEM_PROCESS_INFORMATION2 {
- ULONG NextEntryOffset;
- ULONG NumberOfThreads;
- LARGE_INTEGER SpareLi1;
- LARGE_INTEGER SpareLi2;
- LARGE_INTEGER SpareLi3;
- LARGE_INTEGER CreateTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER KernelTime;
- UNICODE_STRING ImageName;
- LONG BasePriority;
- HANDLE UniqueProcessId;
- HANDLE InheritedFromUniqueProcessId;
- ULONG HandleCount;
- ULONG SessionId;
- ULONG_PTR PageDirectoryBase;
- SIZE_T PeakVirtualSize;
- SIZE_T VirtualSize;
- DWORD PageFaultCount;
- SIZE_T PeakWorkingSetSize;
- SIZE_T WorkingSetSize;
- SIZE_T QuotaPeakPagedPoolUsage;
- SIZE_T QuotaPagedPoolUsage;
- SIZE_T QuotaPeakNonPagedPoolUsage;
- SIZE_T QuotaNonPagedPoolUsage;
- SIZE_T PagefileUsage;
- SIZE_T PeakPagefileUsage;
- SIZE_T PrivatePageCount;
- LARGE_INTEGER ReadOperationCount;
- LARGE_INTEGER WriteOperationCount;
- LARGE_INTEGER OtherOperationCount;
- LARGE_INTEGER ReadTransferCount;
- LARGE_INTEGER WriteTransferCount;
- LARGE_INTEGER OtherTransferCount;
- SYSTEM_THREAD_INFORMATION Threads[1];
-} SYSTEM_PROCESS_INFORMATION2, *PSYSTEM_PROCESS_INFORMATION2;
-
-#define SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION2
-#define PSYSTEM_PROCESS_INFORMATION PSYSTEM_PROCESS_INFORMATION2
-
-
-// ================================================
-// psutil.users() support
-// ================================================
-
-typedef struct _WINSTATION_INFO {
- BYTE Reserved1[72];
- ULONG SessionId;
- BYTE Reserved2[4];
- FILETIME ConnectTime;
- FILETIME DisconnectTime;
- FILETIME LastInputTime;
- FILETIME LoginTime;
- BYTE Reserved3[1096];
- FILETIME CurrentTime;
-} WINSTATION_INFO, *PWINSTATION_INFO;
-
-typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
- (HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
-
-
-/*
- * NtQueryInformationProcess code taken from
- * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
- * typedefs needed to compile against ntdll functions not exposted in the API
- */
-typedef LONG NTSTATUS;
-
-typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
- HANDLE ProcessHandle,
- DWORD ProcessInformationClass,
- PVOID ProcessInformation,
- DWORD ProcessInformationLength,
- PDWORD ReturnLength
-);
-
-typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
- HANDLE ProcessHandle,
- DWORD ProcessInformationClass,
- PVOID ProcessInformation,
- DWORD ProcessInformationLength
-);
-
-
-typedef enum _PROCESSINFOCLASS2 {
- _ProcessBasicInformation,
- ProcessQuotaLimits,
- ProcessIoCounters,
- ProcessVmCounters,
- ProcessTimes,
- ProcessBasePriority,
- ProcessRaisePriority,
- ProcessDebugPort,
- ProcessExceptionPort,
- ProcessAccessToken,
- ProcessLdtInformation,
- ProcessLdtSize,
- ProcessDefaultHardErrorMode,
- ProcessIoPortHandlers,
- ProcessPooledUsageAndLimits,
- ProcessWorkingSetWatch,
- ProcessUserModeIOPL,
- ProcessEnableAlignmentFaultFixup,
- ProcessPriorityClass,
- ProcessWx86Information,
- ProcessHandleCount,
- ProcessAffinityMask,
- ProcessPriorityBoost,
- ProcessDeviceMap,
- ProcessSessionInformation,
- ProcessForegroundInformation,
- _ProcessWow64Information,
- /* added after XP+ */
- ProcessImageFileName,
- ProcessLUIDDeviceMapsEnabled,
- ProcessBreakOnTermination,
- ProcessDebugObjectHandle,
- ProcessDebugFlags,
- ProcessHandleTracing,
- ProcessIoPriority,
- ProcessExecuteFlags,
- ProcessResourceManagement,
- ProcessCookie,
- ProcessImageInformation,
- MaxProcessInfoClass
-} PROCESSINFOCLASS2;
-
-#define PROCESSINFOCLASS PROCESSINFOCLASS2
-#define ProcessBasicInformation _ProcessBasicInformation
-#define ProcessWow64Information _ProcessWow64Information
-
-#endif // __NTEXTAPI_H__
diff --git a/python/psutil/psutil/arch/windows/process_handles.c b/python/psutil/psutil/arch/windows/process_handles.c
deleted file mode 100644
index b3f480af5..000000000
--- a/python/psutil/psutil/arch/windows/process_handles.c
+++ /dev/null
@@ -1,533 +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 "process_handles.h"
-
-static _NtQuerySystemInformation __NtQuerySystemInformation = NULL;
-static _NtQueryObject __NtQueryObject = NULL;
-
-CRITICAL_SECTION g_cs;
-BOOL g_initialized = FALSE;
-NTSTATUS g_status;
-HANDLE g_hFile = NULL;
-HANDLE g_hEvtStart = NULL;
-HANDLE g_hEvtFinish = NULL;
-HANDLE g_hThread = NULL;
-PUNICODE_STRING g_pNameBuffer = NULL;
-ULONG g_dwSize = 0;
-ULONG g_dwLength = 0;
-PVOID g_fiber = NULL;
-
-
-PVOID
-GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
-{
- return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
-}
-
-PyObject *
-psutil_get_open_files(long dwPid, HANDLE hProcess)
-{
- OSVERSIONINFO osvi;
-
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
-
- // Threaded version only works for Vista+
- if (osvi.dwMajorVersion >= 6)
- return psutil_get_open_files_ntqueryobject(dwPid, hProcess);
- else
- return psutil_get_open_files_getmappedfilename(dwPid, hProcess);
-}
-
-VOID
-psutil_get_open_files_init(BOOL threaded)
-{
- if (g_initialized == TRUE)
- return;
-
- // Resolve the Windows API calls
- __NtQuerySystemInformation =
- GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
- __NtQueryObject = GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
-
- // Create events for signalling work between threads
- if (threaded == TRUE) {
- g_hEvtStart = CreateEvent(NULL, FALSE, FALSE, NULL);
- g_hEvtFinish = CreateEvent(NULL, FALSE, FALSE, NULL);
- InitializeCriticalSection(&g_cs);
- }
-
- g_initialized = TRUE;
-}
-
-PyObject *
-psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
-{
- NTSTATUS status;
- PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
- DWORD dwInfoSize = 0x10000;
- DWORD dwRet = 0;
- PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX hHandle = NULL;
- DWORD i = 0;
- BOOLEAN error = FALSE;
- PyObject* pyListFiles = NULL;
- PyObject* pyFilePath = NULL;
- DWORD dwWait = 0;
-
- if (g_initialized == FALSE)
- psutil_get_open_files_init(TRUE);
-
- // Due to the use of global variables, ensure only 1 call
- // to psutil_get_open_files() is running
- EnterCriticalSection(&g_cs);
-
- if (__NtQuerySystemInformation == NULL ||
- __NtQueryObject == NULL ||
- g_hEvtStart == NULL ||
- g_hEvtFinish == NULL)
-
- {
- PyErr_SetFromWindowsErr(0);
- error = TRUE;
- goto cleanup;
- }
-
- // Py_BuildValue raises an exception if NULL is returned
- pyListFiles = PyList_New(0);
- if (pyListFiles == NULL) {
- error = TRUE;
- goto cleanup;
- }
-
- do {
- if (pHandleInfo != NULL) {
- HeapFree(GetProcessHeap(), 0, pHandleInfo);
- pHandleInfo = NULL;
- }
-
- // NtQuerySystemInformation won't give us the correct buffer size,
- // so we guess by doubling the buffer size.
- dwInfoSize *= 2;
- pHandleInfo = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- dwInfoSize);
-
- if (pHandleInfo == NULL) {
- PyErr_NoMemory();
- error = TRUE;
- goto cleanup;
- }
- } while ((status = __NtQuerySystemInformation(
- SystemExtendedHandleInformation,
- pHandleInfo,
- dwInfoSize,
- &dwRet)) == STATUS_INFO_LENGTH_MISMATCH);
-
- // NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH
- if (!NT_SUCCESS(status)) {
- PyErr_SetFromWindowsErr(HRESULT_FROM_NT(status));
- error = TRUE;
- goto cleanup;
- }
-
- for (i = 0; i < pHandleInfo->NumberOfHandles; i++) {
- hHandle = &pHandleInfo->Handles[i];
-
- // Check if this hHandle belongs to the PID the user specified.
- if (hHandle->UniqueProcessId != (HANDLE)dwPid ||
- hHandle->ObjectTypeIndex != HANDLE_TYPE_FILE)
- goto loop_cleanup;
-
- if (!DuplicateHandle(hProcess,
- hHandle->HandleValue,
- GetCurrentProcess(),
- &g_hFile,
- 0,
- TRUE,
- DUPLICATE_SAME_ACCESS))
- {
- /*
- printf("[%d] DuplicateHandle (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- goto loop_cleanup;
- }
-
- // Guess buffer size is MAX_PATH + 1
- g_dwLength = (MAX_PATH+1) * sizeof(WCHAR);
-
- do {
- // Release any previously allocated buffer
- if (g_pNameBuffer != NULL) {
- HeapFree(GetProcessHeap(), 0, g_pNameBuffer);
- g_pNameBuffer = NULL;
- g_dwSize = 0;
- }
-
- // NtQueryObject puts the required buffer size in g_dwLength
- // WinXP edge case puts g_dwLength == 0, just skip this handle
- if (g_dwLength == 0)
- goto loop_cleanup;
-
- g_dwSize = g_dwLength;
- if (g_dwSize > 0) {
- g_pNameBuffer = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- g_dwSize);
-
- if (g_pNameBuffer == NULL)
- goto loop_cleanup;
- }
-
- dwWait = psutil_NtQueryObject();
-
- // If the call does not return, skip this handle
- if (dwWait != WAIT_OBJECT_0)
- goto loop_cleanup;
-
- } while (g_status == STATUS_INFO_LENGTH_MISMATCH);
-
- // NtQueryObject stopped returning STATUS_INFO_LENGTH_MISMATCH
- if (!NT_SUCCESS(g_status))
- goto loop_cleanup;
-
- // Convert to PyUnicode and append it to the return list
- if (g_pNameBuffer->Length > 0) {
- /*
- printf("[%d] Filename (%#x) %#d bytes: %S\n",
- dwPid,
- hHandle->HandleValue,
- g_pNameBuffer->Length,
- g_pNameBuffer->Buffer);
- */
-
- pyFilePath = PyUnicode_FromWideChar(g_pNameBuffer->Buffer,
- g_pNameBuffer->Length/2);
- if (pyFilePath == NULL) {
- /*
- printf("[%d] PyUnicode_FromWideChar (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- error = TRUE;
- goto loop_cleanup;
- }
-
- if (PyList_Append(pyListFiles, pyFilePath)) {
- /*
- printf("[%d] PyList_Append (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- error = TRUE;
- goto loop_cleanup;
- }
- }
-
-loop_cleanup:
- Py_XDECREF(pyFilePath);
- pyFilePath = NULL;
-
- if (g_pNameBuffer != NULL)
- HeapFree(GetProcessHeap(), 0, g_pNameBuffer);
- g_pNameBuffer = NULL;
- g_dwSize = 0;
- g_dwLength = 0;
-
- if (g_hFile != NULL)
- CloseHandle(g_hFile);
- g_hFile = NULL;
- }
-
-cleanup:
- if (g_pNameBuffer != NULL)
- HeapFree(GetProcessHeap(), 0, g_pNameBuffer);
- g_pNameBuffer = NULL;
- g_dwSize = 0;
- g_dwLength = 0;
-
- if (g_hFile != NULL)
- CloseHandle(g_hFile);
- g_hFile = NULL;
-
- if (pHandleInfo != NULL)
- HeapFree(GetProcessHeap(), 0, pHandleInfo);
- pHandleInfo = NULL;
-
- if (error) {
- Py_XDECREF(pyListFiles);
- pyListFiles = NULL;
- }
-
- LeaveCriticalSection(&g_cs);
-
- return pyListFiles;
-}
-
-DWORD
-psutil_NtQueryObject()
-{
- DWORD dwWait = 0;
-
- if (g_hThread == NULL)
- g_hThread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)psutil_NtQueryObjectThread,
- NULL,
- 0,
- NULL);
- if (g_hThread == NULL)
- return GetLastError();
-
- // Signal the worker thread to start
- SetEvent(g_hEvtStart);
-
- // Wait for the worker thread to finish
- dwWait = WaitForSingleObject(g_hEvtFinish, NTQO_TIMEOUT);
-
- // If the thread hangs, kill it and cleanup
- if (dwWait == WAIT_TIMEOUT) {
- SuspendThread(g_hThread);
- TerminateThread(g_hThread, 1);
- WaitForSingleObject(g_hThread, INFINITE);
- CloseHandle(g_hThread);
-
- // Cleanup Fiber
- if (g_fiber != NULL)
- DeleteFiber(g_fiber);
- g_fiber = NULL;
-
- g_hThread = NULL;
- }
-
- return dwWait;
-}
-
-void
-psutil_NtQueryObjectThread()
-{
- // Prevent the thread stack from leaking when this
- // thread gets terminated due to NTQueryObject hanging
- g_fiber = ConvertThreadToFiber(NULL);
-
- // Loop infinitely waiting for work
- while (TRUE) {
- WaitForSingleObject(g_hEvtStart, INFINITE);
-
- g_status = __NtQueryObject(g_hFile,
- ObjectNameInformation,
- g_pNameBuffer,
- g_dwSize,
- &g_dwLength);
- SetEvent(g_hEvtFinish);
- }
-}
-
-PyObject *
-psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
-{
- NTSTATUS status;
- PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
- DWORD dwInfoSize = 0x10000;
- DWORD dwRet = 0;
- PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX hHandle = NULL;
- HANDLE hFile = NULL;
- HANDLE hMap = NULL;
- DWORD i = 0;
- BOOLEAN error = FALSE;
- PyObject* pyListFiles = NULL;
- PyObject* pyFilePath = NULL;
- ULONG dwSize = 0;
- LPVOID pMem = NULL;
- TCHAR pszFilename[MAX_PATH+1];
-
- if (g_initialized == FALSE)
- psutil_get_open_files_init(FALSE);
-
- if (__NtQuerySystemInformation == NULL || __NtQueryObject == NULL) {
- PyErr_SetFromWindowsErr(0);
- error = TRUE;
- goto cleanup;
- }
-
- // Py_BuildValue raises an exception if NULL is returned
- pyListFiles = PyList_New(0);
- if (pyListFiles == NULL) {
- error = TRUE;
- goto cleanup;
- }
-
- do {
- if (pHandleInfo != NULL) {
- HeapFree(GetProcessHeap(), 0, pHandleInfo);
- pHandleInfo = NULL;
- }
-
- // NtQuerySystemInformation won't give us the correct buffer size,
- // so we guess by doubling the buffer size.
- dwInfoSize *= 2;
- pHandleInfo = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- dwInfoSize);
-
- if (pHandleInfo == NULL) {
- PyErr_NoMemory();
- error = TRUE;
- goto cleanup;
- }
- } while ((status = __NtQuerySystemInformation(
- SystemExtendedHandleInformation,
- pHandleInfo,
- dwInfoSize,
- &dwRet)) == STATUS_INFO_LENGTH_MISMATCH);
-
- // NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH
- if (!NT_SUCCESS(status)) {
- PyErr_SetFromWindowsErr(HRESULT_FROM_NT(status));
- error = TRUE;
- goto cleanup;
- }
-
- for (i = 0; i < pHandleInfo->NumberOfHandles; i++) {
- hHandle = &pHandleInfo->Handles[i];
-
- // Check if this hHandle belongs to the PID the user specified.
- if (hHandle->UniqueProcessId != (HANDLE)dwPid ||
- hHandle->ObjectTypeIndex != HANDLE_TYPE_FILE)
- goto loop_cleanup;
-
- if (!DuplicateHandle(hProcess,
- hHandle->HandleValue,
- GetCurrentProcess(),
- &hFile,
- 0,
- TRUE,
- DUPLICATE_SAME_ACCESS))
- {
- /*
- printf("[%d] DuplicateHandle (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- goto loop_cleanup;
- }
-
- hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (hMap == NULL) {
- /*
- printf("[%d] CreateFileMapping (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- goto loop_cleanup;
- }
-
- pMem = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 1);
-
- if (pMem == NULL) {
- /*
- printf("[%d] MapViewOfFile (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- goto loop_cleanup;
- }
-
- dwSize = GetMappedFileName(GetCurrentProcess(), pMem, pszFilename, MAX_PATH);
- if (dwSize == 0) {
- /*
- printf("[%d] GetMappedFileName (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- goto loop_cleanup;
- }
-
- pszFilename[dwSize] = '\0';
- /*
- printf("[%d] Filename (%#x) %#d bytes: %S\n",
- dwPid,
- hHandle->HandleValue,
- dwSize,
- pszFilename);
- */
-
- pyFilePath = PyUnicode_FromWideChar(pszFilename, dwSize);
- if (pyFilePath == NULL) {
- /*
- printf("[%d] PyUnicode_FromStringAndSize (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- error = TRUE;
- goto loop_cleanup;
- }
-
- if (PyList_Append(pyListFiles, pyFilePath)) {
- /*
- printf("[%d] PyList_Append (%#x): %#x \n",
- dwPid,
- hHandle->HandleValue,
- GetLastError());
- */
- error = TRUE;
- goto loop_cleanup;
- }
-
-loop_cleanup:
- Py_XDECREF(pyFilePath);
- pyFilePath = NULL;
-
- if (pMem != NULL)
- UnmapViewOfFile(pMem);
- pMem = NULL;
-
- if (hMap != NULL)
- CloseHandle(hMap);
- hMap = NULL;
-
- if (hFile != NULL)
- CloseHandle(hFile);
- hFile = NULL;
-
- dwSize = 0;
- }
-
-cleanup:
- if (pMem != NULL)
- UnmapViewOfFile(pMem);
- pMem = NULL;
-
- if (hMap != NULL)
- CloseHandle(hMap);
- hMap = NULL;
-
- if (hFile != NULL)
- CloseHandle(hFile);
- hFile = NULL;
-
- if (pHandleInfo != NULL)
- HeapFree(GetProcessHeap(), 0, pHandleInfo);
- pHandleInfo = NULL;
-
- if (error) {
- Py_XDECREF(pyListFiles);
- pyListFiles = NULL;
- }
-
- return pyListFiles;
-}
diff --git a/python/psutil/psutil/arch/windows/process_handles.h b/python/psutil/psutil/arch/windows/process_handles.h
deleted file mode 100644
index 4cf4023ec..000000000
--- a/python/psutil/psutil/arch/windows/process_handles.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef __PROCESS_HANDLES_H__
-#define __PROCESS_HANDLES_H__
-
-#ifndef UNICODE
-#define UNICODE
-#endif
-
-#include <Python.h>
-#include <stdio.h>
-#include <windows.h>
-#include <strsafe.h>
-#include <winternl.h>
-#include <psapi.h>
-
-
-#ifndef NT_SUCCESS
-#define NT_SUCCESS(x) ((x) >= 0)
-#endif
-
-#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
-#define ObjectBasicInformation 0
-#define ObjectNameInformation 1
-#define ObjectTypeInformation 2
-#define HANDLE_TYPE_FILE 28
-#define NTQO_TIMEOUT 100
-
-typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
- ULONG SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
-);
-
-typedef NTSTATUS (NTAPI *_NtQueryObject)(
- HANDLE ObjectHandle,
- ULONG ObjectInformationClass,
- PVOID ObjectInformation,
- ULONG ObjectInformationLength,
- PULONG ReturnLength
-);
-
-// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
-static const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64;
-
-typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
-{
- PVOID Object;
- HANDLE UniqueProcessId;
- HANDLE HandleValue;
- ULONG GrantedAccess;
- USHORT CreatorBackTraceIndex;
- USHORT ObjectTypeIndex;
- ULONG HandleAttributes;
- ULONG Reserved;
-} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
-
-typedef struct _SYSTEM_HANDLE_INFORMATION_EX
-{
- ULONG_PTR NumberOfHandles;
- ULONG_PTR Reserved;
- SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
-} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
-
-typedef enum _POOL_TYPE {
- NonPagedPool,
- PagedPool,
- NonPagedPoolMustSucceed,
- DontUseThisType,
- NonPagedPoolCacheAligned,
- PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS
-} POOL_TYPE, *PPOOL_TYPE;
-
-typedef struct _OBJECT_TYPE_INFORMATION {
- UNICODE_STRING Name;
- ULONG TotalNumberOfObjects;
- ULONG TotalNumberOfHandles;
- ULONG TotalPagedPoolUsage;
- ULONG TotalNonPagedPoolUsage;
- ULONG TotalNamePoolUsage;
- ULONG TotalHandleTableUsage;
- ULONG HighWaterNumberOfObjects;
- ULONG HighWaterNumberOfHandles;
- ULONG HighWaterPagedPoolUsage;
- ULONG HighWaterNonPagedPoolUsage;
- ULONG HighWaterNamePoolUsage;
- ULONG HighWaterHandleTableUsage;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccess;
- BOOLEAN SecurityRequired;
- BOOLEAN MaintainHandleCount;
- USHORT MaintainTypeList;
- POOL_TYPE PoolType;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
-} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
-
-PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName);
-VOID psutil_get_open_files_init(BOOL threaded);
-PyObject* psutil_get_open_files(long pid, HANDLE processHandle);
-PyObject* psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess);
-PyObject* psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess);
-DWORD psutil_NtQueryObject(void);
-void psutil_NtQueryObjectThread(void);
-
-#endif // __PROCESS_HANDLES_H__
diff --git a/python/psutil/psutil/arch/windows/process_info.c b/python/psutil/psutil/arch/windows/process_info.c
deleted file mode 100644
index a59cce47a..000000000
--- a/python/psutil/psutil/arch/windows/process_info.c
+++ /dev/null
@@ -1,435 +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_windows module methods.
- */
-
-#include <Python.h>
-#include <windows.h>
-#include <Psapi.h>
-#include <tlhelp32.h>
-
-#include "security.h"
-#include "process_info.h"
-#include "ntextapi.h"
-#include "../../_psutil_common.h"
-
-
-/*
- * A wrapper around OpenProcess setting NSP exception if process
- * no longer exists.
- * "pid" is the process pid, "dwDesiredAccess" is the first argument
- * exptected by OpenProcess.
- * Return a process handle or NULL.
- */
-HANDLE
-psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
-{
- HANDLE hProcess;
- DWORD processExitCode = 0;
-
- if (pid == 0) {
- // otherwise we'd get NoSuchProcess
- return AccessDenied();
- }
-
- hProcess = OpenProcess(dwDesiredAccess, FALSE, pid);
- if (hProcess == NULL) {
- if (GetLastError() == ERROR_INVALID_PARAMETER)
- NoSuchProcess();
- else
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
-
- // make sure the process is running
- GetExitCodeProcess(hProcess, &processExitCode);
- if (processExitCode == 0) {
- NoSuchProcess();
- CloseHandle(hProcess);
- return NULL;
- }
- return hProcess;
-}
-
-
-/*
- * Same as psutil_handle_from_pid_waccess but implicitly uses
- * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
- * parameter for OpenProcess.
- */
-HANDLE
-psutil_handle_from_pid(DWORD pid) {
- DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
- return psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
-}
-
-
-// fetch the PEB base address from NtQueryInformationProcess()
-PVOID
-psutil_get_peb_address(HANDLE ProcessHandle)
-{
- _NtQueryInformationProcess NtQueryInformationProcess =
- (_NtQueryInformationProcess)GetProcAddress(
- GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
- PROCESS_BASIC_INFORMATION pbi;
-
- NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
- return pbi.PebBaseAddress;
-}
-
-
-DWORD *
-psutil_get_pids(DWORD *numberOfReturnedPIDs) {
- // Win32 SDK says the only way to know if our process array
- // wasn't large enough is to check the returned size and make
- // sure that it doesn't match the size of the array.
- // If it does we allocate a larger array and try again
-
- // Stores the actual array
- DWORD *procArray = NULL;
- DWORD procArrayByteSz;
- int procArraySz = 0;
-
- // Stores the byte size of the returned array from enumprocesses
- DWORD enumReturnSz = 0;
-
- do {
- procArraySz += 1024;
- free(procArray);
- procArrayByteSz = procArraySz * sizeof(DWORD);
- procArray = malloc(procArrayByteSz);
- if (procArray == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) {
- free(procArray);
- PyErr_SetFromWindowsErr(0);
- return NULL;
- }
- } while (enumReturnSz == procArraySz * sizeof(DWORD));
-
- // The number of elements is the returned size / size of each element
- *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD);
-
- return procArray;
-}
-
-
-int
-psutil_pid_is_running(DWORD pid)
-{
- HANDLE hProcess;
- DWORD exitCode;
-
- // Special case for PID 0 System Idle Process
- if (pid == 0)
- return 1;
- if (pid < 0)
- return 0;
-
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, pid);
- if (NULL == hProcess) {
- // invalid parameter is no such process
- if (GetLastError() == ERROR_INVALID_PARAMETER) {
- CloseHandle(hProcess);
- return 0;
- }
-
- // access denied obviously means there's a process to deny access to...
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- CloseHandle(hProcess);
- return 1;
- }
-
- CloseHandle(hProcess);
- PyErr_SetFromWindowsErr(0);
- return -1;
- }
-
- if (GetExitCodeProcess(hProcess, &exitCode)) {
- CloseHandle(hProcess);
- return (exitCode == STILL_ACTIVE);
- }
-
- // access denied means there's a process there so we'll assume
- // it's running
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- CloseHandle(hProcess);
- return 1;
- }
-
- PyErr_SetFromWindowsErr(0);
- CloseHandle(hProcess);
- return -1;
-}
-
-
-int
-psutil_pid_in_proclist(DWORD pid)
-{
- DWORD *proclist = NULL;
- DWORD numberOfReturnedPIDs;
- DWORD i;
-
- proclist = psutil_get_pids(&numberOfReturnedPIDs);
- if (proclist == NULL)
- return -1;
- for (i = 0; i < numberOfReturnedPIDs; i++) {
- if (pid == proclist[i]) {
- free(proclist);
- return 1;
- }
- }
-
- free(proclist);
- return 0;
-}
-
-
-// Check exit code from a process handle. Return FALSE on an error also
-// XXX - not used anymore
-int
-handlep_is_running(HANDLE hProcess)
-{
- DWORD dwCode;
-
- if (NULL == hProcess)
- return 0;
- if (GetExitCodeProcess(hProcess, &dwCode)) {
- if (dwCode == STILL_ACTIVE)
- return 1;
- }
- return 0;
-}
-
-
-/*
- * returns a Python list representing the arguments for the process
- * with given pid or NULL on error.
- */
-PyObject *
-psutil_get_arg_list(long pid)
-{
- int nArgs, i;
- LPWSTR *szArglist = NULL;
- HANDLE hProcess = NULL;
- PVOID pebAddress;
- PVOID rtlUserProcParamsAddress;
- UNICODE_STRING commandLine;
- WCHAR *commandLineContents = NULL;
- PyObject *arg = NULL;
- PyObject *arg_from_wchar = NULL;
- PyObject *argList = NULL;
-
- hProcess = psutil_handle_from_pid(pid);
- if (hProcess == NULL)
- return NULL;
- pebAddress = psutil_get_peb_address(hProcess);
-
- // get the address of ProcessParameters
-#ifdef _WIN64
- if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
- &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
-#else
- if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
- &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
-#endif
- {
- ////printf("Could not read the address of ProcessParameters!\n");
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- // read the CommandLine UNICODE_STRING structure
-#ifdef _WIN64
- if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
- &commandLine, sizeof(commandLine), NULL))
-#else
- if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
- &commandLine, sizeof(commandLine), NULL))
-#endif
- {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
-
- // allocate memory to hold the command line
- commandLineContents = (WCHAR *)malloc(commandLine.Length + 1);
- if (commandLineContents == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- // read the command line
- if (!ReadProcessMemory(hProcess, commandLine.Buffer,
- commandLineContents, commandLine.Length, NULL))
- {
- PyErr_SetFromWindowsErr(0);
- goto error;
- }
-
- // Null-terminate the string to prevent wcslen from returning
- // incorrect length the length specifier is in characters, but
- // commandLine.Length is in bytes.
- commandLineContents[(commandLine.Length / sizeof(WCHAR))] = '\0';
-
- // attempt tp parse the command line using Win32 API, fall back
- // on string cmdline version otherwise
- szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
- if (NULL == szArglist) {
- // failed to parse arglist
- // encode as a UTF8 Python string object from WCHAR string
- arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
- commandLine.Length / 2);
- if (arg_from_wchar == NULL)
- goto error;
-#if PY_MAJOR_VERSION >= 3
- argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
-#else
- argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
-#endif
- if (!argList)
- goto error;
- }
- else {
- // arglist parsed as array of UNICODE_STRING, so convert each to
- // Python string object and add to arg list
- argList = Py_BuildValue("[]");
- if (argList == NULL)
- goto error;
- for (i = 0; i < nArgs; i++) {
- arg_from_wchar = NULL;
- arg = NULL;
- arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
- wcslen(szArglist[i]));
- if (arg_from_wchar == NULL)
- goto error;
-#if PY_MAJOR_VERSION >= 3
- arg = PyUnicode_FromObject(arg_from_wchar);
-#else
- arg = PyUnicode_AsUTF8String(arg_from_wchar);
-#endif
- if (arg == NULL)
- goto error;
- Py_XDECREF(arg_from_wchar);
- if (PyList_Append(argList, arg))
- goto error;
- Py_XDECREF(arg);
- }
- }
-
- if (szArglist != NULL)
- LocalFree(szArglist);
- free(commandLineContents);
- CloseHandle(hProcess);
- return argList;
-
-error:
- Py_XDECREF(arg);
- Py_XDECREF(arg_from_wchar);
- Py_XDECREF(argList);
- if (hProcess != NULL)
- CloseHandle(hProcess);
- if (commandLineContents != NULL)
- free(commandLineContents);
- if (szArglist != NULL)
- LocalFree(szArglist);
- return NULL;
-}
-
-
-#define PH_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
-#define PH_NEXT_PROCESS(Process) ( \
- ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
- (PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
- ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
- NULL)
-
-const int STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
-const int STATUS_BUFFER_TOO_SMALL = 0xC0000023L;
-
-/*
- * Given a process PID and a PSYSTEM_PROCESS_INFORMATION structure
- * fills the structure with various process information by using
- * NtQuerySystemInformation.
- * We use this as a fallback when faster functions fail with access
- * denied. This is slower because it iterates over all processes.
- * On success return 1, else 0 with Python exception already set.
- */
-int
-psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
- PVOID *retBuffer)
-{
- static ULONG initialBufferSize = 0x4000;
- NTSTATUS status;
- PVOID buffer;
- ULONG bufferSize;
- PSYSTEM_PROCESS_INFORMATION process;
-
- // get NtQuerySystemInformation
- typedef DWORD (_stdcall * NTQSI_PROC) (int, PVOID, ULONG, PULONG);
- NTQSI_PROC NtQuerySystemInformation;
- HINSTANCE hNtDll;
- hNtDll = LoadLibrary(TEXT("ntdll.dll"));
- NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
- hNtDll, "NtQuerySystemInformation");
-
- bufferSize = initialBufferSize;
- buffer = malloc(bufferSize);
- if (buffer == NULL) {
- PyErr_NoMemory();
- goto error;
- }
-
- while (TRUE) {
- status = NtQuerySystemInformation(SystemProcessInformation, buffer,
- bufferSize, &bufferSize);
-
- if (status == STATUS_BUFFER_TOO_SMALL ||
- status == STATUS_INFO_LENGTH_MISMATCH)
- {
- free(buffer);
- buffer = malloc(bufferSize);
- if (buffer == NULL) {
- PyErr_NoMemory();
- goto error;
- }
- }
- else {
- break;
- }
- }
-
- if (status != 0) {
- PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
- goto error;
- }
-
- if (bufferSize <= 0x20000)
- initialBufferSize = bufferSize;
-
- process = PH_FIRST_PROCESS(buffer);
- do {
- if (process->UniqueProcessId == (HANDLE)pid) {
- *retProcess = process;
- *retBuffer = buffer;
- return 1;
- }
- } while ( (process = PH_NEXT_PROCESS(process)) );
-
- NoSuchProcess();
- goto error;
-
-error:
- FreeLibrary(hNtDll);
- if (buffer != NULL)
- free(buffer);
- return 0;
-}
diff --git a/python/psutil/psutil/arch/windows/process_info.h b/python/psutil/psutil/arch/windows/process_info.h
deleted file mode 100644
index a44c4aced..000000000
--- a/python/psutil/psutil/arch/windows/process_info.h
+++ /dev/null
@@ -1,26 +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.
- */
-
-#if !defined(__PROCESS_INFO_H)
-#define __PROCESS_INFO_H
-
-#include <Python.h>
-#include <windows.h>
-#include "security.h"
-#include "ntextapi.h"
-
-DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
-HANDLE psutil_handle_from_pid(DWORD pid);
-HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
-int psutil_handlep_is_running(HANDLE hProcess);
-int psutil_pid_in_proclist(DWORD pid);
-int psutil_pid_is_running(DWORD pid);
-PVOID psutil_get_peb_address(HANDLE ProcessHandle);
-PyObject* psutil_get_arg_list(long pid);
-int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
- PVOID *retBuffer);
-
-#endif
diff --git a/python/psutil/psutil/arch/windows/security.c b/python/psutil/psutil/arch/windows/security.c
deleted file mode 100644
index 3aabffd0c..000000000
--- a/python/psutil/psutil/arch/windows/security.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Security related functions for Windows platform (Set privileges such as
- * SeDebug), as well as security helper functions.
- */
-
-#include <windows.h>
-#include <Python.h>
-
-
-/*
- * Convert a process handle to a process token handle.
- */
-HANDLE
-psutil_token_from_handle(HANDLE hProcess) {
- HANDLE hToken = NULL;
-
- if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
- return PyErr_SetFromWindowsErr(0);
- return hToken;
-}
-
-
-/*
- * http://www.ddj.com/windows/184405986
- *
- * There's a way to determine whether we're running under the Local System
- * account. However (you guessed it), we have to call more Win32 functions to
- * determine this. Backing up through the code listing, we need to make another
- * call to GetTokenInformation, but instead of passing through the TOKEN_USER
- * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns
- * an array of privileges that the account has in the environment. Iterating
- * through the array, we call the function LookupPrivilegeName looking for the
- * string SeTcbPrivilege. If the function returns this string, then this
- * account has Local System privileges
- */
-int
-psutil_has_system_privilege(HANDLE hProcess) {
- DWORD i;
- DWORD dwSize = 0;
- DWORD dwRetval = 0;
- TCHAR privName[256];
- DWORD dwNameSize = 256;
- // PTOKEN_PRIVILEGES tp = NULL;
- BYTE *pBuffer = NULL;
- TOKEN_PRIVILEGES *tp = NULL;
- HANDLE hToken = psutil_token_from_handle(hProcess);
-
- if (NULL == hToken)
- return -1;
- // call GetTokenInformation first to get the buffer size
- if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) {
- dwRetval = GetLastError();
- // if it failed for a reason other than the buffer, bail out
- if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) {
- PyErr_SetFromWindowsErr(dwRetval);
- return 0;
- }
- }
-
- // allocate buffer and call GetTokenInformation again
- // tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
- pBuffer = (BYTE *) malloc(dwSize);
- if (pBuffer == NULL) {
- PyErr_NoMemory();
- return -1;
- }
-
- if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer,
- dwSize, &dwSize))
- {
- PyErr_SetFromWindowsErr(0);
- free(pBuffer);
- return -1;
- }
-
- // convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer
- tp = (TOKEN_PRIVILEGES *)pBuffer;
-
- // check all the privileges looking for SeTcbPrivilege
- for (i = 0; i < tp->PrivilegeCount; i++) {
- // reset the buffer contents and the buffer size
- strcpy(privName, "");
- dwNameSize = sizeof(privName) / sizeof(TCHAR);
- if (! LookupPrivilegeName(NULL,
- &tp->Privileges[i].Luid,
- (LPTSTR)privName,
- &dwNameSize))
- {
- PyErr_SetFromWindowsErr(0);
- free(pBuffer);
- return -1;
- }
-
- // if we find the SeTcbPrivilege then it's a LocalSystem process
- if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) {
- free(pBuffer);
- return 1;
- }
- }
-
- free(pBuffer);
- return 0;
-}
-
-
-BOOL
-psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
-{
- TOKEN_PRIVILEGES tp;
- LUID luid;
- TOKEN_PRIVILEGES tpPrevious;
- DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
-
- if (!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
-
- // first pass. get current privilege setting
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = 0;
-
- AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tp,
- sizeof(TOKEN_PRIVILEGES),
- &tpPrevious,
- &cbPrevious
- );
-
- if (GetLastError() != ERROR_SUCCESS) return FALSE;
-
- // second pass. set privilege based on previous setting
- tpPrevious.PrivilegeCount = 1;
- tpPrevious.Privileges[0].Luid = luid;
-
- if (bEnablePrivilege)
- tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
- else
- tpPrevious.Privileges[0].Attributes ^=
- (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
-
- AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tpPrevious,
- cbPrevious,
- NULL,
- NULL
- );
-
- if (GetLastError() != ERROR_SUCCESS) return FALSE;
-
- return TRUE;
-}
-
-
-int
-psutil_set_se_debug()
-{
- HANDLE hToken;
- if (! OpenThreadToken(GetCurrentThread(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- FALSE,
- &hToken)
- ) {
- if (GetLastError() == ERROR_NO_TOKEN) {
- if (!ImpersonateSelf(SecurityImpersonation)) {
- CloseHandle(hToken);
- return 0;
- }
- if (!OpenThreadToken(GetCurrentThread(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- FALSE,
- &hToken)
- ) {
- RevertToSelf();
- CloseHandle(hToken);
- return 0;
- }
- }
- }
-
- // enable SeDebugPrivilege (open any process)
- if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, TRUE)) {
- RevertToSelf();
- CloseHandle(hToken);
- return 0;
- }
-
- RevertToSelf();
- CloseHandle(hToken);
- return 1;
-}
-
-
-int
-psutil_unset_se_debug()
-{
- HANDLE hToken;
- if (! OpenThreadToken(GetCurrentThread(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- FALSE,
- &hToken)
- ) {
- if (GetLastError() == ERROR_NO_TOKEN) {
- if (! ImpersonateSelf(SecurityImpersonation))
- return 0;
- if (!OpenThreadToken(GetCurrentThread(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- FALSE,
- &hToken))
- {
- return 0;
- }
- }
- }
-
- // now disable SeDebug
- if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, FALSE))
- return 0;
-
- CloseHandle(hToken);
- return 1;
-}
diff --git a/python/psutil/psutil/arch/windows/security.h b/python/psutil/psutil/arch/windows/security.h
deleted file mode 100644
index aa8a22ad1..000000000
--- a/python/psutil/psutil/arch/windows/security.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Security related functions for Windows platform (Set privileges such as
- * SeDebug), as well as security helper functions.
- */
-
-#include <windows.h>
-
-BOOL psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege);
-HANDLE psutil_token_from_handle(HANDLE hProcess);
-int psutil_has_system_privilege(HANDLE hProcess);
-int psutil_set_se_debug();
-int psutil_unset_se_debug();
-
diff --git a/python/psutil/setup.cfg b/python/psutil/setup.cfg
deleted file mode 100644
index 861a9f554..000000000
--- a/python/psutil/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[egg_info]
-tag_build =
-tag_date = 0
-tag_svn_revision = 0
-
diff --git a/python/psutil/setup.py b/python/psutil/setup.py
deleted file mode 100644
index 4c42548ef..000000000
--- a/python/psutil/setup.py
+++ /dev/null
@@ -1,206 +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.
-
-"""psutil is a cross-platform library for retrieving information on
-running processes and system utilization (CPU, memory, disks, network)
-in Python.
-"""
-
-import os
-import sys
-try:
- from setuptools import setup, Extension
-except ImportError:
- from distutils.core import setup, Extension
-
-
-HERE = os.path.abspath(os.path.dirname(__file__))
-
-
-def get_version():
- INIT = os.path.join(HERE, 'psutil/__init__.py')
- with open(INIT, 'r') as f:
- for line in f:
- if line.startswith('__version__'):
- ret = eval(line.strip().split(' = ')[1])
- assert ret.count('.') == 2, ret
- for num in ret.split('.'):
- assert num.isdigit(), ret
- return ret
- else:
- raise ValueError("couldn't find version string")
-
-
-def get_description():
- README = os.path.join(HERE, 'README.rst')
- with open(README, 'r') as f:
- return f.read()
-
-
-VERSION = get_version()
-VERSION_MACRO = ('PSUTIL_VERSION', int(VERSION.replace('.', '')))
-
-
-# POSIX
-if os.name == 'posix':
- libraries = []
- if sys.platform.startswith("sunos"):
- libraries.append('socket')
-
- posix_extension = Extension(
- 'psutil._psutil_posix',
- sources=['psutil/_psutil_posix.c'],
- libraries=libraries,
- )
-# Windows
-if sys.platform.startswith("win32"):
-
- def get_winver():
- maj, min = sys.getwindowsversion()[0:2]
- return '0x0%s' % ((maj * 100) + min)
-
- extensions = [Extension(
- 'psutil._psutil_windows',
- sources=[
- 'psutil/_psutil_windows.c',
- 'psutil/_psutil_common.c',
- 'psutil/arch/windows/process_info.c',
- 'psutil/arch/windows/process_handles.c',
- 'psutil/arch/windows/security.c',
- 'psutil/arch/windows/inet_ntop.c',
- ],
- define_macros=[
- VERSION_MACRO,
- # be nice to mingw, see:
- # http://www.mingw.org/wiki/Use_more_recent_defined_functions
- ('_WIN32_WINNT', get_winver()),
- ('_AVAIL_WINVER_', get_winver()),
- ('_CRT_SECURE_NO_WARNINGS', None),
- # see: https://github.com/giampaolo/psutil/issues/348
- ('PSAPI_VERSION', 1),
- ],
- libraries=[
- "psapi", "kernel32", "advapi32", "shell32", "netapi32", "iphlpapi",
- "wtsapi32", "ws2_32",
- ],
- # extra_compile_args=["/Z7"],
- # extra_link_args=["/DEBUG"]
- )]
-# OS X
-elif sys.platform.startswith("darwin"):
- extensions = [Extension(
- 'psutil._psutil_osx',
- sources=[
- 'psutil/_psutil_osx.c',
- 'psutil/_psutil_common.c',
- 'psutil/arch/osx/process_info.c'
- ],
- define_macros=[VERSION_MACRO],
- extra_link_args=[
- '-framework', 'CoreFoundation', '-framework', 'IOKit'
- ],
- ),
- posix_extension,
- ]
-# FreeBSD
-elif sys.platform.startswith("freebsd"):
- extensions = [Extension(
- 'psutil._psutil_bsd',
- sources=[
- 'psutil/_psutil_bsd.c',
- 'psutil/_psutil_common.c',
- 'psutil/arch/bsd/process_info.c'
- ],
- define_macros=[VERSION_MACRO],
- libraries=["devstat"]),
- posix_extension,
- ]
-# Linux
-elif sys.platform.startswith("linux"):
- extensions = [Extension(
- 'psutil._psutil_linux',
- sources=['psutil/_psutil_linux.c'],
- define_macros=[VERSION_MACRO]),
- posix_extension,
- ]
-# Solaris
-elif sys.platform.lower().startswith('sunos'):
- extensions = [Extension(
- 'psutil._psutil_sunos',
- sources=['psutil/_psutil_sunos.c'],
- define_macros=[VERSION_MACRO],
- libraries=['kstat', 'nsl', 'socket']),
- posix_extension,
- ]
-else:
- sys.exit('platform %s is not supported' % sys.platform)
-
-
-def main():
- setup_args = dict(
- name='psutil',
- version=VERSION,
- description=__doc__.replace('\n', '').strip(),
- long_description=get_description(),
- keywords=[
- 'ps', 'top', 'kill', 'free', 'lsof', 'netstat', 'nice', 'tty',
- 'ionice', 'uptime', 'taskmgr', 'process', 'df', 'iotop', 'iostat',
- 'ifconfig', 'taskset', 'who', 'pidof', 'pmap', 'smem', 'pstree',
- 'monitoring', 'ulimit', 'prlimit',
- ],
- author='Giampaolo Rodola',
- author_email='g.rodola <at> gmail <dot> com',
- url='https://github.com/giampaolo/psutil',
- platforms='Platform Independent',
- license='BSD',
- packages=['psutil'],
- # see: python setup.py register --list-classifiers
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Console',
- 'Environment :: Win32 (MS Windows)',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Information Technology',
- 'Intended Audience :: System Administrators',
- 'License :: OSI Approved :: BSD License',
- 'Operating System :: MacOS :: MacOS X',
- 'Operating System :: Microsoft :: Windows :: Windows NT/2000',
- 'Operating System :: Microsoft',
- 'Operating System :: OS Independent',
- 'Operating System :: POSIX :: BSD :: FreeBSD',
- 'Operating System :: POSIX :: Linux',
- 'Operating System :: POSIX :: SunOS/Solaris',
- 'Operating System :: POSIX',
- 'Programming Language :: C',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.0',
- 'Programming Language :: Python :: 3.1',
- 'Programming Language :: Python :: 3.2',
- 'Programming Language :: Python :: 3.3',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: Implementation :: CPython',
- 'Programming Language :: Python :: Implementation :: PyPy',
- 'Programming Language :: Python',
- 'Topic :: Software Development :: Libraries :: Python Modules',
- 'Topic :: Software Development :: Libraries',
- 'Topic :: System :: Benchmark',
- 'Topic :: System :: Hardware',
- 'Topic :: System :: Monitoring',
- 'Topic :: System :: Networking :: Monitoring',
- 'Topic :: System :: Networking',
- 'Topic :: System :: Systems Administration',
- 'Topic :: Utilities',
- ],
- )
- if extensions is not None:
- setup_args["ext_modules"] = extensions
- setup(**setup_args)
-
-if __name__ == '__main__':
- main()
diff --git a/python/psutil/test/README.rst b/python/psutil/test/README.rst
deleted file mode 100644
index 3f2a468ef..000000000
--- a/python/psutil/test/README.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-- The recommended way to run tests (also on Windows) is to cd into parent
- directory and run ``make test``
-
-- Dependencies for running tests:
- - python 2.6: ipaddress, mock, unittest2
- - python 2.7: ipaddress, mock
- - python 3.2: ipaddress, mock
- - python 3.3: ipaddress
- - python >= 3.4: no deps required
-
-- The main test script is ``test_psutil.py``, which also imports platform-specific
- ``_*.py`` scripts (which should be ignored).
-
-- ``test_memory_leaks.py`` looks for memory leaks into C extension modules and must
- be run separately with ``make test-memleaks``.
-
-- To run tests on all supported Python version install tox (pip install tox)
- then run ``tox``.
-
-- Every time a commit is pushed tests are automatically run on Travis:
- https://travis-ci.org/giampaolo/psutil/
diff --git a/python/psutil/test/_bsd.py b/python/psutil/test/_bsd.py
deleted file mode 100644
index e4a3225d2..000000000
--- a/python/psutil/test/_bsd.py
+++ /dev/null
@@ -1,252 +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.
-
-# TODO: add test for comparing connections with 'sockstat' cmd
-
-"""BSD specific tests. These are implicitly run by test_psutil.py."""
-
-import os
-import subprocess
-import sys
-import time
-
-import psutil
-
-from psutil._compat import PY3
-from test_psutil import (TOLERANCE, BSD, sh, get_test_subprocess, which,
- retry_before_failing, reap_children, unittest)
-
-
-PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-if os.getuid() == 0: # muse requires root privileges
- MUSE_AVAILABLE = which('muse')
-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)
- result = result[result.find(": ") + 2:]
- 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])
-
-
-@unittest.skipUnless(BSD, "not a BSD system")
-class BSDSpecificTestCase(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_boot_time(self):
- s = sysctl('sysctl kern.boottime')
- s = s[s.find(" sec = ") + 7:]
- s = s[:s.find(',')]
- btime = int(s)
- self.assertEqual(btime, psutil.boot_time())
-
- def test_process_create_time(self):
- cmdline = "ps -o lstart -p %s" % self.pid
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0]
- if PY3:
- output = str(output, sys.stdout.encoding)
- start_ps = output.replace('STARTED', '').strip()
- start_psutil = psutil.Process(self.pid).create_time()
- start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
- time.localtime(start_psutil))
- self.assertEqual(start_ps, start_psutil)
-
- def test_disks(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -k "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total = int(total) * 1024
- used = int(used) * 1024
- free = int(free) * 1024
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(part.device, dev)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.free, free))
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.used, used))
-
- @retry_before_failing()
- def test_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_exe(self):
- out = sh('procstat -b %s' % self.pid)
- self.assertEqual(psutil.Process(self.pid).exe(),
- out.split('\n')[1].split()[-1])
-
- def test_cmdline(self):
- out = sh('procstat -c %s' % self.pid)
- self.assertEqual(' '.join(psutil.Process(self.pid).cmdline()),
- ' '.join(out.split('\n')[1].split()[2:]))
-
- def test_uids_gids(self):
- out = sh('procstat -s %s' % self.pid)
- euid, ruid, suid, egid, rgid, sgid = out.split('\n')[1].split()[2:8]
- p = psutil.Process(self.pid)
- uids = p.uids()
- gids = p.gids()
- self.assertEqual(uids.real, int(ruid))
- self.assertEqual(uids.effective, int(euid))
- self.assertEqual(uids.saved, int(suid))
- self.assertEqual(gids.real, int(rgid))
- self.assertEqual(gids.effective, int(egid))
- self.assertEqual(gids.saved, int(sgid))
-
- # --- virtual_memory(); tests against sysctl
-
- def test_vmem_total(self):
- syst = sysctl("sysctl vm.stats.vm.v_page_count") * PAGESIZE
- self.assertEqual(psutil.virtual_memory().total, syst)
-
- @retry_before_failing()
- def test_vmem_active(self):
- syst = sysctl("vm.stats.vm.v_active_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().active, syst,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_inactive(self):
- syst = sysctl("vm.stats.vm.v_inactive_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().inactive, syst,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_wired(self):
- syst = sysctl("vm.stats.vm.v_wire_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().wired, syst,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_cached(self):
- syst = sysctl("vm.stats.vm.v_cache_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().cached, syst,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_free(self):
- syst = sysctl("vm.stats.vm.v_free_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().free, syst,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_buffers(self):
- syst = sysctl("vfs.bufspace")
- self.assertAlmostEqual(psutil.virtual_memory().buffers, syst,
- delta=TOLERANCE)
-
- def test_cpu_count_logical(self):
- syst = sysctl("hw.ncpu")
- self.assertEqual(psutil.cpu_count(logical=True), syst)
-
- # --- virtual_memory(); tests against muse
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- def test_total(self):
- num = muse('Total')
- self.assertEqual(psutil.virtual_memory().total, num)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_active(self):
- num = muse('Active')
- self.assertAlmostEqual(psutil.virtual_memory().active, num,
- delta=TOLERANCE)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_inactive(self):
- num = muse('Inactive')
- self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
- delta=TOLERANCE)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_wired(self):
- num = muse('Wired')
- self.assertAlmostEqual(psutil.virtual_memory().wired, num,
- delta=TOLERANCE)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_cached(self):
- num = muse('Cache')
- self.assertAlmostEqual(psutil.virtual_memory().cached, num,
- delta=TOLERANCE)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_free(self):
- num = muse('Free')
- self.assertAlmostEqual(psutil.virtual_memory().free, num,
- delta=TOLERANCE)
-
- @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
- @retry_before_failing()
- def test_buffers(self):
- num = muse('Buffer')
- self.assertAlmostEqual(psutil.virtual_memory().buffers, num,
- delta=TOLERANCE)
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/_linux.py b/python/psutil/test/_linux.py
deleted file mode 100644
index c1927ea8b..000000000
--- a/python/psutil/test/_linux.py
+++ /dev/null
@@ -1,473 +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.
-
-"""Linux specific tests. These are implicitly run by test_psutil.py."""
-
-from __future__ import division
-import contextlib
-import errno
-import fcntl
-import io
-import os
-import pprint
-import re
-import socket
-import struct
-import sys
-import tempfile
-import time
-import warnings
-
-try:
- from unittest import mock # py3
-except ImportError:
- import mock # requires "pip install mock"
-
-from test_psutil import POSIX, TOLERANCE, TRAVIS, LINUX
-from test_psutil import (skip_on_not_implemented, sh, get_test_subprocess,
- retry_before_failing, get_kernel_version, unittest,
- which, call_until)
-
-import psutil
-import psutil._pslinux
-from psutil._compat import PY3, u
-
-
-SIOCGIFADDR = 0x8915
-SIOCGIFCONF = 0x8912
-SIOCGIFHWADDR = 0x8927
-
-
-def get_ipv4_address(ifname):
- ifname = ifname[:15]
- if PY3:
- ifname = bytes(ifname, 'ascii')
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- with contextlib.closing(s):
- return socket.inet_ntoa(
- fcntl.ioctl(s.fileno(),
- SIOCGIFADDR,
- struct.pack('256s', ifname))[20:24])
-
-
-def get_mac_address(ifname):
- ifname = ifname[:15]
- if PY3:
- ifname = bytes(ifname, 'ascii')
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- with contextlib.closing(s):
- info = fcntl.ioctl(
- s.fileno(), SIOCGIFHWADDR, struct.pack('256s', ifname))
- if PY3:
- def ord(x):
- return x
- else:
- import __builtin__
- ord = __builtin__.ord
- return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
-
-
-@unittest.skipUnless(LINUX, "not a Linux system")
-class LinuxSpecificTestCase(unittest.TestCase):
-
- @unittest.skipIf(
- POSIX and not hasattr(os, 'statvfs'),
- reason="os.statvfs() function not available on this platform")
- @skip_on_not_implemented()
- def test_disks(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -P -B 1 "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total, used, free = int(total), int(used), int(free)
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(part.device, dev)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.free, free))
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.used, used))
-
- def test_memory_maps(self):
- sproc = get_test_subprocess()
- time.sleep(1)
- p = psutil.Process(sproc.pid)
- maps = p.memory_maps(grouped=False)
- pmap = sh('pmap -x %s' % p.pid).split('\n')
- # get rid of header
- del pmap[0]
- del pmap[0]
- while maps and pmap:
- this = maps.pop(0)
- other = pmap.pop(0)
- addr, _, rss, dirty, mode, path = other.split(None, 5)
- if not path.startswith('[') and not path.endswith(']'):
- self.assertEqual(path, os.path.basename(this.path))
- self.assertEqual(int(rss) * 1024, this.rss)
- # test only rwx chars, ignore 's' and 'p'
- self.assertEqual(mode[:3], this.perms[:3])
-
- def test_vmem_total(self):
- lines = sh('free').split('\n')[1:]
- total = int(lines[0].split()[1]) * 1024
- self.assertEqual(total, psutil.virtual_memory().total)
-
- @retry_before_failing()
- def test_vmem_used(self):
- lines = sh('free').split('\n')[1:]
- used = int(lines[0].split()[2]) * 1024
- self.assertAlmostEqual(used, psutil.virtual_memory().used,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_free(self):
- lines = sh('free').split('\n')[1:]
- free = int(lines[0].split()[3]) * 1024
- self.assertAlmostEqual(free, psutil.virtual_memory().free,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_buffers(self):
- lines = sh('free').split('\n')[1:]
- buffers = int(lines[0].split()[5]) * 1024
- self.assertAlmostEqual(buffers, psutil.virtual_memory().buffers,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_cached(self):
- lines = sh('free').split('\n')[1:]
- cached = int(lines[0].split()[6]) * 1024
- self.assertAlmostEqual(cached, psutil.virtual_memory().cached,
- delta=TOLERANCE)
-
- def test_swapmem_total(self):
- lines = sh('free').split('\n')[1:]
- total = int(lines[2].split()[1]) * 1024
- self.assertEqual(total, psutil.swap_memory().total)
-
- @retry_before_failing()
- def test_swapmem_used(self):
- lines = sh('free').split('\n')[1:]
- used = int(lines[2].split()[2]) * 1024
- self.assertAlmostEqual(used, psutil.swap_memory().used,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_swapmem_free(self):
- lines = sh('free').split('\n')[1:]
- free = int(lines[2].split()[3]) * 1024
- self.assertAlmostEqual(free, psutil.swap_memory().free,
- delta=TOLERANCE)
-
- @unittest.skipIf(TRAVIS, "unknown failure on travis")
- def test_cpu_times(self):
- fields = psutil.cpu_times()._fields
- kernel_ver = re.findall('\d+\.\d+\.\d+', os.uname()[2])[0]
- kernel_ver_info = tuple(map(int, kernel_ver.split('.')))
- if kernel_ver_info >= (2, 6, 11):
- self.assertIn('steal', fields)
- else:
- self.assertNotIn('steal', fields)
- if kernel_ver_info >= (2, 6, 24):
- self.assertIn('guest', fields)
- else:
- self.assertNotIn('guest', fields)
- if kernel_ver_info >= (3, 2, 0):
- self.assertIn('guest_nice', fields)
- else:
- self.assertNotIn('guest_nice', fields)
-
- def test_net_if_addrs_ips(self):
- for name, addrs in psutil.net_if_addrs().items():
- for addr in addrs:
- if addr.family == psutil.AF_LINK:
- self.assertEqual(addr.address, get_mac_address(name))
- elif addr.family == socket.AF_INET:
- self.assertEqual(addr.address, get_ipv4_address(name))
- # TODO: test for AF_INET6 family
-
- @unittest.skipUnless(which('ip'), "'ip' utility not available")
- @unittest.skipIf(TRAVIS, "skipped on Travis")
- def test_net_if_names(self):
- out = sh("ip addr").strip()
- nics = psutil.net_if_addrs()
- found = 0
- for line in out.split('\n'):
- line = line.strip()
- if re.search("^\d+:", line):
- found += 1
- name = line.split(':')[1].strip()
- self.assertIn(name, nics.keys())
- self.assertEqual(len(nics), found, msg="%s\n---\n%s" % (
- pprint.pformat(nics), out))
-
- @unittest.skipUnless(which("nproc"), "nproc utility not available")
- def test_cpu_count_logical_w_nproc(self):
- num = int(sh("nproc --all"))
- self.assertEqual(psutil.cpu_count(logical=True), num)
-
- @unittest.skipUnless(which("lscpu"), "lscpu utility not available")
- def test_cpu_count_logical_w_lscpu(self):
- out = sh("lscpu -p")
- num = len([x for x in out.split('\n') if not x.startswith('#')])
- self.assertEqual(psutil.cpu_count(logical=True), num)
-
- # --- mocked tests
-
- def test_virtual_memory_mocked_warnings(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter("always")
- ret = psutil._pslinux.virtual_memory()
- assert m.called
- self.assertEqual(len(ws), 1)
- w = ws[0]
- self.assertTrue(w.filename.endswith('psutil/_pslinux.py'))
- self.assertIn(
- "'cached', 'active' and 'inactive' memory stats couldn't "
- "be determined", str(w.message))
- self.assertEqual(ret.cached, 0)
- self.assertEqual(ret.active, 0)
- self.assertEqual(ret.inactive, 0)
-
- def test_swap_memory_mocked_warnings(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter("always")
- ret = psutil._pslinux.swap_memory()
- assert m.called
- self.assertEqual(len(ws), 1)
- w = ws[0]
- self.assertTrue(w.filename.endswith('psutil/_pslinux.py'))
- self.assertIn(
- "'sin' and 'sout' swap memory stats couldn't "
- "be determined", str(w.message))
- self.assertEqual(ret.sin, 0)
- self.assertEqual(ret.sout, 0)
-
- def test_cpu_count_logical_mocked(self):
- import psutil._pslinux
- original = psutil._pslinux.cpu_count_logical()
- # Here we want to mock os.sysconf("SC_NPROCESSORS_ONLN") in
- # order to cause the parsing of /proc/cpuinfo and /proc/stat.
- with mock.patch(
- 'psutil._pslinux.os.sysconf', side_effect=ValueError) as m:
- self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
- assert m.called
-
- # Let's have open() return emtpy data and make sure None is
- # returned ('cause we mimick os.cpu_count()).
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertIsNone(psutil._pslinux.cpu_count_logical())
- self.assertEqual(m.call_count, 2)
- # /proc/stat should be the last one
- self.assertEqual(m.call_args[0][0], '/proc/stat')
-
- # Let's push this a bit further and make sure /proc/cpuinfo
- # parsing works as expected.
- with open('/proc/cpuinfo', 'rb') as f:
- cpuinfo_data = f.read()
- fake_file = io.BytesIO(cpuinfo_data)
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
-
- def test_cpu_count_physical_mocked(self):
- # Have open() return emtpy data and make sure None is returned
- # ('cause we want to mimick os.cpu_count())
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertIsNone(psutil._pslinux.cpu_count_physical())
- assert m.called
-
- def test_proc_open_files_file_gone(self):
- # simulates a file which gets deleted during open_files()
- # execution
- p = psutil.Process()
- files = p.open_files()
- with tempfile.NamedTemporaryFile():
- # give the kernel some time to see the new file
- call_until(p.open_files, "len(ret) != %i" % len(files))
- with mock.patch('psutil._pslinux.os.readlink',
- side_effect=OSError(errno.ENOENT, "")) as m:
- files = p.open_files()
- assert not files
- assert m.called
- # also simulate the case where os.readlink() returns EINVAL
- # in which case psutil is supposed to 'continue'
- with mock.patch('psutil._pslinux.os.readlink',
- side_effect=OSError(errno.EINVAL, "")) as m:
- self.assertEqual(p.open_files(), [])
- assert m.called
-
- def test_proc_terminal_mocked(self):
- with mock.patch('psutil._pslinux._psposix._get_terminal_map',
- return_value={}) as m:
- self.assertIsNone(psutil._pslinux.Process(os.getpid()).terminal())
- assert m.called
-
- def test_proc_num_ctx_switches_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).num_ctx_switches)
- assert m.called
-
- def test_proc_num_threads_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).num_threads)
- assert m.called
-
- def test_proc_ppid_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).ppid)
- assert m.called
-
- def test_proc_uids_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).uids)
- assert m.called
-
- def test_proc_gids_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).gids)
- assert m.called
-
- def test_proc_cmdline_mocked(self):
- # see: https://github.com/giampaolo/psutil/issues/639
- p = psutil.Process()
- fake_file = io.StringIO(u('foo\x00bar\x00'))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- p.cmdline() == ['foo', 'bar']
- assert m.called
- fake_file = io.StringIO(u('foo\x00bar\x00\x00'))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- p.cmdline() == ['foo', 'bar', '']
- assert m.called
-
- def test_proc_io_counters_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- NotImplementedError,
- psutil._pslinux.Process(os.getpid()).io_counters)
- assert m.called
-
- def test_boot_time_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- RuntimeError,
- psutil._pslinux.boot_time)
- assert m.called
-
- def test_users_mocked(self):
- # Make sure ':0' and ':0.0' (returned by C ext) are converted
- # to 'localhost'.
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', ':0',
- 1436573184.0, True)]) as m:
- self.assertEqual(psutil.users()[0].host, 'localhost')
- assert m.called
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', ':0.0',
- 1436573184.0, True)]) as m:
- self.assertEqual(psutil.users()[0].host, 'localhost')
- assert m.called
- # ...otherwise it should be returned as-is
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', 'foo',
- 1436573184.0, True)]) as m:
- self.assertEqual(psutil.users()[0].host, 'foo')
- assert m.called
-
- def test_disk_partitions_mocked(self):
- # Test that ZFS partitions are returned.
- with open("/proc/filesystems", "r") as f:
- data = f.read()
- if 'zfs' in data:
- for part in psutil.disk_partitions():
- if part.fstype == 'zfs':
- break
- else:
- self.fail("couldn't find any ZFS partition")
- else:
- # No ZFS partitions on this system. Let's fake one.
- fake_file = io.StringIO(u("nodev\tzfs\n"))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m1:
- with mock.patch(
- 'psutil._pslinux.cext.disk_partitions',
- return_value=[('/dev/sdb3', '/', 'zfs', 'rw')]) as m2:
- ret = psutil.disk_partitions()
- assert m1.called
- assert m2.called
- assert ret
- self.assertEqual(ret[0].fstype, 'zfs')
-
- # --- tests for specific kernel versions
-
- @unittest.skipUnless(
- get_kernel_version() >= (2, 6, 36),
- "prlimit() not available on this Linux kernel version")
- def test_prlimit_availability(self):
- # prlimit() should be available starting from kernel 2.6.36
- p = psutil.Process(os.getpid())
- p.rlimit(psutil.RLIMIT_NOFILE)
- # if prlimit() is supported *at least* these constants should
- # be available
- self.assertTrue(hasattr(psutil, "RLIM_INFINITY"))
- self.assertTrue(hasattr(psutil, "RLIMIT_AS"))
- self.assertTrue(hasattr(psutil, "RLIMIT_CORE"))
- self.assertTrue(hasattr(psutil, "RLIMIT_CPU"))
- self.assertTrue(hasattr(psutil, "RLIMIT_DATA"))
- self.assertTrue(hasattr(psutil, "RLIMIT_FSIZE"))
- self.assertTrue(hasattr(psutil, "RLIMIT_LOCKS"))
- self.assertTrue(hasattr(psutil, "RLIMIT_MEMLOCK"))
- self.assertTrue(hasattr(psutil, "RLIMIT_NOFILE"))
- self.assertTrue(hasattr(psutil, "RLIMIT_NPROC"))
- self.assertTrue(hasattr(psutil, "RLIMIT_RSS"))
- self.assertTrue(hasattr(psutil, "RLIMIT_STACK"))
-
- @unittest.skipUnless(
- get_kernel_version() >= (3, 0),
- "prlimit constants not available on this Linux kernel version")
- def test_resource_consts_kernel_v(self):
- # more recent constants
- self.assertTrue(hasattr(psutil, "RLIMIT_MSGQUEUE"))
- self.assertTrue(hasattr(psutil, "RLIMIT_NICE"))
- self.assertTrue(hasattr(psutil, "RLIMIT_RTPRIO"))
- self.assertTrue(hasattr(psutil, "RLIMIT_RTTIME"))
- self.assertTrue(hasattr(psutil, "RLIMIT_SIGPENDING"))
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(LinuxSpecificTestCase))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/_osx.py b/python/psutil/test/_osx.py
deleted file mode 100644
index 6e6e4380e..000000000
--- a/python/psutil/test/_osx.py
+++ /dev/null
@@ -1,160 +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.
-
-"""OSX specific tests. These are implicitly run by test_psutil.py."""
-
-import os
-import re
-import subprocess
-import sys
-import time
-
-import psutil
-
-from psutil._compat import PY3
-from test_psutil import (TOLERANCE, OSX, sh, get_test_subprocess,
- reap_children, retry_before_failing, unittest)
-
-
-PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-
-
-def sysctl(cmdline):
- """Expects a sysctl command with an argument and parse the result
- returning only the value of interest.
- """
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- result = p.communicate()[0].strip().split()[1]
- if PY3:
- result = str(result, sys.stdout.encoding)
- try:
- return int(result)
- except ValueError:
- return result
-
-
-def vm_stat(field):
- """Wrapper around 'vm_stat' cmdline utility."""
- out = sh('vm_stat')
- for line in out.split('\n'):
- if field in line:
- break
- else:
- raise ValueError("line not found")
- return int(re.search('\d+', line).group(0)) * PAGESIZE
-
-
-@unittest.skipUnless(OSX, "not an OSX system")
-class OSXSpecificTestCase(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_process_create_time(self):
- cmdline = "ps -o lstart -p %s" % self.pid
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0]
- if PY3:
- output = str(output, sys.stdout.encoding)
- start_ps = output.replace('STARTED', '').strip()
- start_psutil = psutil.Process(self.pid).create_time()
- start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
- time.localtime(start_psutil))
- self.assertEqual(start_ps, start_psutil)
-
- def test_disks(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -k "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total = int(total) * 1024
- used = int(used) * 1024
- free = int(free) * 1024
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(part.device, dev)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % usage.free, free)
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % usage.used, used)
-
- # --- virtual mem
-
- def test_vmem_total(self):
- sysctl_hwphymem = sysctl('sysctl hw.memsize')
- self.assertEqual(sysctl_hwphymem, psutil.virtual_memory().total)
-
- @retry_before_failing()
- def test_vmem_free(self):
- num = vm_stat("free")
- self.assertAlmostEqual(psutil.virtual_memory().free, num,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_active(self):
- num = vm_stat("active")
- self.assertAlmostEqual(psutil.virtual_memory().active, num,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_inactive(self):
- num = vm_stat("inactive")
- self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
- delta=TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_wired(self):
- num = vm_stat("wired")
- self.assertAlmostEqual(psutil.virtual_memory().wired, num,
- delta=TOLERANCE)
-
- # --- swap mem
-
- def test_swapmem_sin(self):
- num = vm_stat("Pageins")
- self.assertEqual(psutil.swap_memory().sin, num)
-
- def test_swapmem_sout(self):
- num = vm_stat("Pageouts")
- self.assertEqual(psutil.swap_memory().sout, num)
-
- def test_swapmem_total(self):
- tot1 = psutil.swap_memory().total
- tot2 = 0
- # OSX uses multiple cache files:
- # http://en.wikipedia.org/wiki/Paging#OS_X
- for name in os.listdir("/var/vm/"):
- file = os.path.join("/var/vm", name)
- if os.path.isfile(file):
- tot2 += os.path.getsize(file)
- self.assertEqual(tot1, tot2)
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/_posix.py b/python/psutil/test/_posix.py
deleted file mode 100644
index e6c56aac3..000000000
--- a/python/psutil/test/_posix.py
+++ /dev/null
@@ -1,258 +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.
-
-"""POSIX specific tests. These are implicitly run by test_psutil.py."""
-
-import datetime
-import os
-import subprocess
-import sys
-import time
-
-import psutil
-
-from psutil._compat import PY3, callable
-from test_psutil import LINUX, SUNOS, OSX, BSD, PYTHON, POSIX, TRAVIS
-from test_psutil import (get_test_subprocess, skip_on_access_denied,
- retry_before_failing, reap_children, sh, unittest,
- get_kernel_version, wait_for_pid)
-
-
-def ps(cmd):
- """Expects a ps command with a -o argument and parse the result
- returning only the value of interest.
- """
- if not LINUX:
- cmd = cmd.replace(" --no-headers ", " ")
- if SUNOS:
- cmd = cmd.replace("-o command", "-o comm")
- cmd = cmd.replace("-o start", "-o stime")
- p = subprocess.Popen(cmd, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- if PY3:
- output = str(output, sys.stdout.encoding)
- if not LINUX:
- output = output.split('\n')[1].strip()
- try:
- return int(output)
- except ValueError:
- return output
-
-
-@unittest.skipUnless(POSIX, "not a POSIX system")
-class PosixSpecificTestCase(unittest.TestCase):
- """Compare psutil results against 'ps' command line utility."""
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess([PYTHON, "-E", "-O"],
- stdin=subprocess.PIPE).pid
- wait_for_pid(cls.pid)
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- # for ps -o arguments see: http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
-
- def test_process_parent_pid(self):
- ppid_ps = ps("ps --no-headers -o ppid -p %s" % self.pid)
- ppid_psutil = psutil.Process(self.pid).ppid()
- self.assertEqual(ppid_ps, ppid_psutil)
-
- def test_process_uid(self):
- uid_ps = ps("ps --no-headers -o uid -p %s" % self.pid)
- uid_psutil = psutil.Process(self.pid).uids().real
- self.assertEqual(uid_ps, uid_psutil)
-
- def test_process_gid(self):
- gid_ps = ps("ps --no-headers -o rgid -p %s" % self.pid)
- gid_psutil = psutil.Process(self.pid).gids().real
- self.assertEqual(gid_ps, gid_psutil)
-
- def test_process_username(self):
- username_ps = ps("ps --no-headers -o user -p %s" % self.pid)
- username_psutil = psutil.Process(self.pid).username()
- self.assertEqual(username_ps, username_psutil)
-
- @skip_on_access_denied()
- @retry_before_failing()
- def test_process_rss_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- rss_ps = ps("ps --no-headers -o rss -p %s" % self.pid)
- rss_psutil = psutil.Process(self.pid).memory_info()[0] / 1024
- self.assertEqual(rss_ps, rss_psutil)
-
- @skip_on_access_denied()
- @retry_before_failing()
- def test_process_vsz_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- vsz_ps = ps("ps --no-headers -o vsz -p %s" % self.pid)
- vsz_psutil = psutil.Process(self.pid).memory_info()[1] / 1024
- self.assertEqual(vsz_ps, vsz_psutil)
-
- def test_process_name(self):
- # use command + arg since "comm" keyword not supported on all platforms
- name_ps = ps("ps --no-headers -o command -p %s" % (
- self.pid)).split(' ')[0]
- # remove path if there is any, from the command
- name_ps = os.path.basename(name_ps).lower()
- name_psutil = psutil.Process(self.pid).name().lower()
- self.assertEqual(name_ps, name_psutil)
-
- @unittest.skipIf(OSX or BSD,
- 'ps -o start not available')
- def test_process_create_time(self):
- time_ps = ps("ps --no-headers -o start -p %s" % self.pid).split(' ')[0]
- time_psutil = psutil.Process(self.pid).create_time()
- time_psutil_tstamp = datetime.datetime.fromtimestamp(
- time_psutil).strftime("%H:%M:%S")
- # sometimes ps shows the time rounded up instead of down, so we check
- # for both possible values
- round_time_psutil = round(time_psutil)
- round_time_psutil_tstamp = datetime.datetime.fromtimestamp(
- round_time_psutil).strftime("%H:%M:%S")
- self.assertIn(time_ps, [time_psutil_tstamp, round_time_psutil_tstamp])
-
- def test_process_exe(self):
- ps_pathname = ps("ps --no-headers -o command -p %s" %
- self.pid).split(' ')[0]
- psutil_pathname = psutil.Process(self.pid).exe()
- try:
- self.assertEqual(ps_pathname, psutil_pathname)
- except AssertionError:
- # certain platforms such as BSD are more accurate returning:
- # "/usr/local/bin/python2.7"
- # ...instead of:
- # "/usr/local/bin/python"
- # We do not want to consider this difference in accuracy
- # an error.
- adjusted_ps_pathname = ps_pathname[:len(ps_pathname)]
- self.assertEqual(ps_pathname, adjusted_ps_pathname)
-
- def test_process_cmdline(self):
- ps_cmdline = ps("ps --no-headers -o command -p %s" % self.pid)
- psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline())
- if SUNOS:
- # ps on Solaris only shows the first part of the cmdline
- psutil_cmdline = psutil_cmdline.split(" ")[0]
- self.assertEqual(ps_cmdline, psutil_cmdline)
-
- @retry_before_failing()
- def test_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- if SUNOS:
- cmd = ["ps", "ax"]
- else:
- cmd = ["ps", "ax", "-o", "pid"]
- p = get_test_subprocess(cmd, stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- if PY3:
- output = str(output, sys.stdout.encoding)
- pids_ps = []
- for line in output.split('\n')[1:]:
- if line:
- pid = int(line.split()[0].strip())
- pids_ps.append(pid)
- # remove ps subprocess pid which is supposed to be dead in meantime
- pids_ps.remove(p.pid)
- pids_psutil = psutil.pids()
- pids_ps.sort()
- pids_psutil.sort()
-
- # on OSX ps doesn't show pid 0
- if OSX and 0 not in pids_ps:
- pids_ps.insert(0, 0)
-
- if pids_ps != pids_psutil:
- difference = [x for x in pids_psutil if x not in pids_ps] + \
- [x for x in pids_ps if x not in pids_psutil]
- self.fail("difference: " + str(difference))
-
- # for some reason ifconfig -a does not report all interfaces
- # returned by psutil
- @unittest.skipIf(SUNOS, "test not reliable on SUNOS")
- @unittest.skipIf(TRAVIS, "test not reliable on Travis")
- def test_nic_names(self):
- p = subprocess.Popen("ifconfig -a", shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- if PY3:
- output = str(output, sys.stdout.encoding)
- for nic in psutil.net_io_counters(pernic=True).keys():
- for line in output.split():
- if line.startswith(nic):
- break
- else:
- self.fail(
- "couldn't find %s nic in 'ifconfig -a' output\n%s" % (
- nic, output))
-
- @retry_before_failing()
- def test_users(self):
- out = sh("who")
- lines = out.split('\n')
- users = [x.split()[0] for x in lines]
- self.assertEqual(len(users), len(psutil.users()))
- terminals = [x.split()[1] for x in lines]
- for u in psutil.users():
- self.assertTrue(u.name in users, u.name)
- self.assertTrue(u.terminal in terminals, u.terminal)
-
- def test_fds_open(self):
- # Note: this fails from time to time; I'm keen on thinking
- # it doesn't mean something is broken
- def call(p, attr):
- args = ()
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- if name == 'rlimit':
- args = (psutil.RLIMIT_NOFILE,)
- attr(*args)
- else:
- attr
-
- p = psutil.Process(os.getpid())
- failures = []
- ignored_names = ['terminate', 'kill', 'suspend', 'resume', 'nice',
- 'send_signal', 'wait', 'children', 'as_dict']
- if LINUX and get_kernel_version() < (2, 6, 36):
- ignored_names.append('rlimit')
- if LINUX and get_kernel_version() < (2, 6, 23):
- ignored_names.append('num_ctx_switches')
- for name in dir(psutil.Process):
- if (name.startswith('_') or name in ignored_names):
- continue
- else:
- try:
- num1 = p.num_fds()
- for x in range(2):
- call(p, name)
- num2 = p.num_fds()
- except psutil.AccessDenied:
- pass
- else:
- if abs(num2 - num1) > 1:
- fail = "failure while processing Process.%s method " \
- "(before=%s, after=%s)" % (name, num1, num2)
- failures.append(fail)
- if failures:
- self.fail('\n' + '\n'.join(failures))
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/_sunos.py b/python/psutil/test/_sunos.py
deleted file mode 100644
index 3d54ccd8c..000000000
--- a/python/psutil/test/_sunos.py
+++ /dev/null
@@ -1,48 +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.
-
-"""Sun OS specific tests. These are implicitly run by test_psutil.py."""
-
-import sys
-import os
-
-from test_psutil import SUNOS, sh, unittest
-import psutil
-
-
-@unittest.skipUnless(SUNOS, "not a SunOS system")
-class SunOSSpecificTestCase(unittest.TestCase):
-
- def test_swap_memory(self):
- out = sh('env PATH=/usr/sbin:/sbin:%s swap -l -k' % os.environ['PATH'])
- lines = out.strip().split('\n')[1:]
- if not lines:
- raise ValueError('no swap device(s) configured')
- total = free = 0
- for line in lines:
- line = line.split()
- t, f = line[-2:]
- t = t.replace('K', '')
- f = f.replace('K', '')
- total += int(int(t) * 1024)
- free += int(int(f) * 1024)
- used = total - free
-
- psutil_swap = psutil.swap_memory()
- self.assertEqual(psutil_swap.total, total)
- self.assertEqual(psutil_swap.used, used)
- self.assertEqual(psutil_swap.free, free)
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(SunOSSpecificTestCase))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/_windows.py b/python/psutil/test/_windows.py
deleted file mode 100644
index b7477bfeb..000000000
--- a/python/psutil/test/_windows.py
+++ /dev/null
@@ -1,464 +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.
-
-"""Windows specific tests. These are implicitly run by test_psutil.py."""
-
-import errno
-import os
-import platform
-import signal
-import subprocess
-import sys
-import time
-import traceback
-
-from test_psutil import APPVEYOR, WINDOWS
-from test_psutil import get_test_subprocess, reap_children, unittest
-
-import mock
-try:
- import wmi
-except ImportError:
- wmi = None
-try:
- import win32api
- import win32con
-except ImportError:
- win32api = win32con = None
-
-from psutil._compat import PY3, callable, long
-import psutil
-
-
-cext = psutil._psplatform.cext
-
-
-def wrap_exceptions(fun):
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except OSError as err:
- from psutil._pswindows import ACCESS_DENIED_SET
- if err.errno in ACCESS_DENIED_SET:
- raise psutil.AccessDenied(None, None)
- if err.errno == errno.ESRCH:
- raise psutil.NoSuchProcess(None, None)
- raise
- return wrapper
-
-
-@unittest.skipUnless(WINDOWS, "not a Windows system")
-class WindowsSpecificTestCase(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_issue_24(self):
- p = psutil.Process(0)
- self.assertRaises(psutil.AccessDenied, p.kill)
-
- def test_special_pid(self):
- p = psutil.Process(4)
- self.assertEqual(p.name(), 'System')
- # use __str__ to access all common Process properties to check
- # that nothing strange happens
- str(p)
- p.username()
- self.assertTrue(p.create_time() >= 0.0)
- try:
- rss, vms = p.memory_info()
- except psutil.AccessDenied:
- # expected on Windows Vista and Windows 7
- if not platform.uname()[1] in ('vista', 'win-7', 'win7'):
- raise
- else:
- self.assertTrue(rss > 0)
-
- def test_send_signal(self):
- p = psutil.Process(self.pid)
- self.assertRaises(ValueError, p.send_signal, signal.SIGINT)
-
- def test_nic_names(self):
- p = subprocess.Popen(['ipconfig', '/all'], stdout=subprocess.PIPE)
- out = p.communicate()[0]
- if PY3:
- out = str(out, sys.stdout.encoding)
- nics = psutil.net_io_counters(pernic=True).keys()
- for nic in nics:
- if "pseudo-interface" in nic.replace(' ', '-').lower():
- continue
- if nic not in out:
- self.fail(
- "%r nic wasn't found in 'ipconfig /all' output" % nic)
-
- def test_exe(self):
- for p in psutil.process_iter():
- try:
- self.assertEqual(os.path.basename(p.exe()), p.name())
- except psutil.Error:
- pass
-
- # --- Process class tests
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_name(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(p.name(), w.Caption)
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_exe(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- # Note: wmi reports the exe as a lower case string.
- # Being Windows paths case-insensitive we ignore that.
- self.assertEqual(p.exe().lower(), w.ExecutablePath.lower())
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_cmdline(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(' '.join(p.cmdline()),
- w.CommandLine.replace('"', ''))
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_username(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- domain, _, username = w.GetOwner()
- username = "%s\\%s" % (domain, username)
- self.assertEqual(p.username(), username)
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_rss_memory(self):
- time.sleep(0.1)
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- rss = p.memory_info().rss
- self.assertEqual(rss, int(w.WorkingSetSize))
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_vms_memory(self):
- time.sleep(0.1)
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- vms = p.memory_info().vms
- # http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx
- # ...claims that PageFileUsage is represented in Kilo
- # bytes but funnily enough on certain platforms bytes are
- # returned instead.
- wmi_usage = int(w.PageFileUsage)
- if (vms != wmi_usage) and (vms != wmi_usage * 1024):
- self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms))
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_process_create_time(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- time.localtime(p.create_time()))
- self.assertEqual(wmic_create, psutil_create)
-
- # --- psutil namespace functions and constants tests
-
- @unittest.skipUnless('NUMBER_OF_PROCESSORS' in os.environ,
- 'NUMBER_OF_PROCESSORS env var is not available')
- def test_cpu_count(self):
- num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
- self.assertEqual(num_cpus, psutil.cpu_count())
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_total_phymem(self):
- w = wmi.WMI().Win32_ComputerSystem()[0]
- self.assertEqual(int(w.TotalPhysicalMemory),
- psutil.virtual_memory().total)
-
- # @unittest.skipIf(wmi is None, "wmi module is not installed")
- # def test__UPTIME(self):
- # # _UPTIME constant is not public but it is used internally
- # # as value to return for pid 0 creation time.
- # # WMI behaves the same.
- # w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- # p = psutil.Process(0)
- # wmic_create = str(w.CreationDate.split('.')[0])
- # psutil_create = time.strftime("%Y%m%d%H%M%S",
- # time.localtime(p.create_time()))
- #
-
- # Note: this test is not very reliable
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- @unittest.skipIf(APPVEYOR, "test not relieable on appveyor")
- def test_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- w = wmi.WMI().Win32_Process()
- wmi_pids = set([x.ProcessId for x in w])
- psutil_pids = set(psutil.pids())
- self.assertEqual(wmi_pids, psutil_pids)
-
- @unittest.skipIf(wmi is None, "wmi module is not installed")
- def test_disks(self):
- ps_parts = psutil.disk_partitions(all=True)
- wmi_parts = wmi.WMI().Win32_LogicalDisk()
- for ps_part in ps_parts:
- for wmi_part in wmi_parts:
- if ps_part.device.replace('\\', '') == wmi_part.DeviceID:
- if not ps_part.mountpoint:
- # this is usually a CD-ROM with no disk inserted
- break
- try:
- usage = psutil.disk_usage(ps_part.mountpoint)
- except OSError as err:
- if err.errno == errno.ENOENT:
- # usually this is the floppy
- break
- else:
- raise
- self.assertEqual(usage.total, int(wmi_part.Size))
- wmi_free = int(wmi_part.FreeSpace)
- self.assertEqual(usage.free, wmi_free)
- # 10 MB tollerance
- if abs(usage.free - wmi_free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, wmi=%s" % (
- usage.free, wmi_free))
- break
- else:
- self.fail("can't find partition %s" % repr(ps_part))
-
- @unittest.skipIf(win32api is None, "pywin32 module is not installed")
- def test_num_handles(self):
- p = psutil.Process(os.getpid())
- before = p.num_handles()
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, os.getpid())
- after = p.num_handles()
- self.assertEqual(after, before + 1)
- win32api.CloseHandle(handle)
- self.assertEqual(p.num_handles(), before)
-
- @unittest.skipIf(win32api is None, "pywin32 module is not installed")
- def test_num_handles_2(self):
- # Note: this fails from time to time; I'm keen on thinking
- # it doesn't mean something is broken
- def call(p, attr):
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- attr()
- else:
- attr
-
- p = psutil.Process(self.pid)
- failures = []
- for name in dir(psutil.Process):
- if name.startswith('_') \
- or name in ('terminate', 'kill', 'suspend', 'resume',
- 'nice', 'send_signal', 'wait', 'children',
- 'as_dict'):
- continue
- else:
- try:
- call(p, name)
- num1 = p.num_handles()
- call(p, name)
- num2 = p.num_handles()
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
- else:
- if num2 > num1:
- fail = \
- "failure while processing Process.%s method " \
- "(before=%s, after=%s)" % (name, num1, num2)
- failures.append(fail)
- if failures:
- self.fail('\n' + '\n'.join(failures))
-
- def test_name_always_available(self):
- # On Windows name() is never supposed to raise AccessDenied,
- # see https://github.com/giampaolo/psutil/issues/627
- for p in psutil.process_iter():
- try:
- p.name()
- except psutil.NoSuchProcess():
- pass
-
-
-@unittest.skipUnless(WINDOWS, "not a Windows system")
-class TestDualProcessImplementation(unittest.TestCase):
- """
- Certain APIs on Windows have 2 internal implementations, one
- based on documented Windows APIs, another one based
- NtQuerySystemInformation() which gets called as fallback in
- case the first fails because of limited permission error.
- Here we test that the two methods return the exact same value,
- see:
- https://github.com/giampaolo/psutil/issues/304
- """
-
- fun_names = [
- # function name, tolerance
- ('proc_cpu_times', 0.2),
- ('proc_create_time', 0.5),
- ('proc_num_handles', 1), # 1 because impl #1 opens a handle
- ('proc_memory_info', 1024), # KB
- ('proc_io_counters', 0),
- ]
-
- def test_compare_values(self):
- def assert_ge_0(obj):
- if isinstance(obj, tuple):
- for value in obj:
- self.assertGreaterEqual(value, 0, msg=obj)
- elif isinstance(obj, (int, long, float)):
- self.assertGreaterEqual(obj, 0)
- else:
- assert 0 # case not handled which needs to be fixed
-
- def compare_with_tolerance(ret1, ret2, tolerance):
- if ret1 == ret2:
- return
- else:
- if isinstance(ret2, (int, long, float)):
- diff = abs(ret1 - ret2)
- self.assertLessEqual(diff, tolerance)
- elif isinstance(ret2, tuple):
- for a, b in zip(ret1, ret2):
- diff = abs(a - b)
- self.assertLessEqual(diff, tolerance)
-
- from psutil._pswindows import ntpinfo
- failures = []
- for p in psutil.process_iter():
- try:
- nt = ntpinfo(*cext.proc_info(p.pid))
- except psutil.NoSuchProcess:
- continue
- assert_ge_0(nt)
-
- for name, tolerance in self.fun_names:
- if name == 'proc_memory_info' and p.pid == os.getpid():
- continue
- if name == 'proc_create_time' and p.pid in (0, 4):
- continue
- meth = wrap_exceptions(getattr(cext, name))
- try:
- ret = meth(p.pid)
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- continue
- # compare values
- try:
- if name == 'proc_cpu_times':
- compare_with_tolerance(ret[0], nt.user_time, tolerance)
- compare_with_tolerance(ret[1],
- nt.kernel_time, tolerance)
- elif name == 'proc_create_time':
- compare_with_tolerance(ret, nt.create_time, tolerance)
- elif name == 'proc_num_handles':
- compare_with_tolerance(ret, nt.num_handles, tolerance)
- elif name == 'proc_io_counters':
- compare_with_tolerance(ret[0], nt.io_rcount, tolerance)
- compare_with_tolerance(ret[1], nt.io_wcount, tolerance)
- compare_with_tolerance(ret[2], nt.io_rbytes, tolerance)
- compare_with_tolerance(ret[3], nt.io_wbytes, tolerance)
- elif name == 'proc_memory_info':
- try:
- rawtupl = cext.proc_memory_info_2(p.pid)
- except psutil.NoSuchProcess:
- continue
- compare_with_tolerance(ret, rawtupl, tolerance)
- except AssertionError:
- trace = traceback.format_exc()
- msg = '%s\npid=%s, method=%r, ret_1=%r, ret_2=%r' % (
- trace, p.pid, name, ret, nt)
- failures.append(msg)
- break
-
- if failures:
- self.fail('\n\n'.join(failures))
-
- # ---
- # same tests as above but mimicks the AccessDenied failure of
- # the first (fast) method failing with AD.
- # TODO: currently does not take tolerance into account.
-
- def test_name(self):
- name = psutil.Process().name()
- with mock.patch("psutil._psplatform.cext.proc_exe",
- side_effect=psutil.AccessDenied(os.getpid())) as fun:
- psutil.Process().name() == name
- assert fun.called
-
- def test_memory_info(self):
- mem = psutil.Process().memory_info()
- with mock.patch("psutil._psplatform.cext.proc_memory_info",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- psutil.Process().memory_info() == mem
- assert fun.called
-
- def test_create_time(self):
- ctime = psutil.Process().create_time()
- with mock.patch("psutil._psplatform.cext.proc_create_time",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- psutil.Process().create_time() == ctime
- assert fun.called
-
- def test_cpu_times(self):
- cpu_times = psutil.Process().cpu_times()
- with mock.patch("psutil._psplatform.cext.proc_cpu_times",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- psutil.Process().cpu_times() == cpu_times
- assert fun.called
-
- def test_io_counters(self):
- io_counters = psutil.Process().io_counters()
- with mock.patch("psutil._psplatform.cext.proc_io_counters",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- psutil.Process().io_counters() == io_counters
- assert fun.called
-
- def test_num_handles(self):
- io_counters = psutil.Process().io_counters()
- with mock.patch("psutil._psplatform.cext.proc_io_counters",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- psutil.Process().io_counters() == io_counters
- assert fun.called
-
- # --- other tests
-
- def test_compare_name_exe(self):
- for p in psutil.process_iter():
- try:
- a = os.path.basename(p.exe())
- b = p.name()
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
- else:
- self.assertEqual(a, b)
-
- def test_zombies(self):
- # test that NPS is raised by the 2nd implementation in case a
- # process no longer exists
- ZOMBIE_PID = max(psutil.pids()) + 5000
- for name, _ in self.fun_names:
- meth = wrap_exceptions(getattr(cext, name))
- self.assertRaises(psutil.NoSuchProcess, meth, ZOMBIE_PID)
-
-
-def main():
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
- test_suite.addTest(unittest.makeSuite(TestDualProcessImplementation))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/test_memory_leaks.py b/python/psutil/test/test_memory_leaks.py
deleted file mode 100644
index 6f02dc0ac..000000000
--- a/python/psutil/test/test_memory_leaks.py
+++ /dev/null
@@ -1,445 +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 test script which attempts to detect memory leaks by calling C
-functions many times and compare process memory usage before and
-after the calls. It might produce false positives.
-"""
-
-import functools
-import gc
-import os
-import socket
-import sys
-import threading
-import time
-
-import psutil
-import psutil._common
-
-from psutil._compat import xrange, callable
-from test_psutil import (WINDOWS, POSIX, OSX, LINUX, SUNOS, BSD, TESTFN,
- RLIMIT_SUPPORT, TRAVIS)
-from test_psutil import (reap_children, supports_ipv6, safe_remove,
- get_test_subprocess)
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest # https://pypi.python.org/pypi/unittest2
-else:
- import unittest
-
-
-LOOPS = 1000
-TOLERANCE = 4096
-SKIP_PYTHON_IMPL = True
-
-
-def skip_if_linux():
- return unittest.skipIf(LINUX and SKIP_PYTHON_IMPL,
- "not worth being tested on LINUX (pure python)")
-
-
-class Base(unittest.TestCase):
- proc = psutil.Process()
-
- def execute(self, function, *args, **kwargs):
- def call_many_times():
- for x in xrange(LOOPS - 1):
- self.call(function, *args, **kwargs)
- del x
- gc.collect()
- return self.get_mem()
-
- self.call(function, *args, **kwargs)
- self.assertEqual(gc.garbage, [])
- self.assertEqual(threading.active_count(), 1)
-
- # RSS comparison
- # step 1
- rss1 = call_many_times()
- # step 2
- rss2 = call_many_times()
-
- difference = rss2 - rss1
- if difference > TOLERANCE:
- # This doesn't necessarily mean we have a leak yet.
- # At this point we assume that after having called the
- # function so many times the memory usage is stabilized
- # and if there are no leaks it should not increase any
- # more.
- # Let's keep calling fun for 3 more seconds and fail if
- # we notice any difference.
- stop_at = time.time() + 3
- while True:
- self.call(function, *args, **kwargs)
- if time.time() >= stop_at:
- break
- del stop_at
- gc.collect()
- rss3 = self.get_mem()
- difference = rss3 - rss2
- if rss3 > rss2:
- self.fail("rss2=%s, rss3=%s, difference=%s"
- % (rss2, rss3, difference))
-
- def execute_w_exc(self, exc, function, *args, **kwargs):
- kwargs['_exc'] = exc
- self.execute(function, *args, **kwargs)
-
- def get_mem(self):
- return psutil.Process().memory_info()[0]
-
- def call(self, function, *args, **kwargs):
- raise NotImplementedError("must be implemented in subclass")
-
-
-class TestProcessObjectLeaks(Base):
- """Test leaks of Process class methods and properties"""
-
- def setUp(self):
- gc.collect()
-
- def tearDown(self):
- reap_children()
-
- def call(self, function, *args, **kwargs):
- if callable(function):
- if '_exc' in kwargs:
- exc = kwargs.pop('_exc')
- self.assertRaises(exc, function, *args, **kwargs)
- else:
- try:
- function(*args, **kwargs)
- except psutil.Error:
- pass
- else:
- meth = getattr(self.proc, function)
- if '_exc' in kwargs:
- exc = kwargs.pop('_exc')
- self.assertRaises(exc, meth, *args, **kwargs)
- else:
- try:
- meth(*args, **kwargs)
- except psutil.Error:
- pass
-
- @skip_if_linux()
- def test_name(self):
- self.execute('name')
-
- @skip_if_linux()
- def test_cmdline(self):
- self.execute('cmdline')
-
- @skip_if_linux()
- def test_exe(self):
- self.execute('exe')
-
- @skip_if_linux()
- def test_ppid(self):
- self.execute('ppid')
-
- @unittest.skipUnless(POSIX, "POSIX only")
- @skip_if_linux()
- def test_uids(self):
- self.execute('uids')
-
- @unittest.skipUnless(POSIX, "POSIX only")
- @skip_if_linux()
- def test_gids(self):
- self.execute('gids')
-
- @skip_if_linux()
- def test_status(self):
- self.execute('status')
-
- def test_nice_get(self):
- self.execute('nice')
-
- def test_nice_set(self):
- niceness = psutil.Process().nice()
- self.execute('nice', niceness)
-
- @unittest.skipUnless(hasattr(psutil.Process, 'ionice'),
- "Linux and Windows Vista only")
- def test_ionice_get(self):
- self.execute('ionice')
-
- @unittest.skipUnless(hasattr(psutil.Process, 'ionice'),
- "Linux and Windows Vista only")
- def test_ionice_set(self):
- if WINDOWS:
- value = psutil.Process().ionice()
- self.execute('ionice', value)
- else:
- from psutil._pslinux import cext
- self.execute('ionice', psutil.IOPRIO_CLASS_NONE)
- fun = functools.partial(cext.proc_ioprio_set, os.getpid(), -1, 0)
- self.execute_w_exc(OSError, fun)
-
- @unittest.skipIf(OSX or SUNOS, "feature not supported on this platform")
- @skip_if_linux()
- def test_io_counters(self):
- self.execute('io_counters')
-
- @unittest.skipUnless(WINDOWS, "not worth being tested on posix")
- def test_username(self):
- self.execute('username')
-
- @skip_if_linux()
- def test_create_time(self):
- self.execute('create_time')
-
- @skip_if_linux()
- def test_num_threads(self):
- self.execute('num_threads')
-
- @unittest.skipUnless(WINDOWS, "Windows only")
- def test_num_handles(self):
- self.execute('num_handles')
-
- @unittest.skipUnless(POSIX, "POSIX only")
- @skip_if_linux()
- def test_num_fds(self):
- self.execute('num_fds')
-
- @skip_if_linux()
- def test_threads(self):
- self.execute('threads')
-
- @skip_if_linux()
- def test_cpu_times(self):
- self.execute('cpu_times')
-
- @skip_if_linux()
- def test_memory_info(self):
- self.execute('memory_info')
-
- @skip_if_linux()
- def test_memory_info_ex(self):
- self.execute('memory_info_ex')
-
- @unittest.skipUnless(POSIX, "POSIX only")
- @skip_if_linux()
- def test_terminal(self):
- self.execute('terminal')
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "not worth being tested on POSIX (pure python)")
- def test_resume(self):
- self.execute('resume')
-
- @skip_if_linux()
- def test_cwd(self):
- self.execute('cwd')
-
- @unittest.skipUnless(WINDOWS or LINUX or BSD,
- "Windows or Linux or BSD only")
- def test_cpu_affinity_get(self):
- self.execute('cpu_affinity')
-
- @unittest.skipUnless(WINDOWS or LINUX or BSD,
- "Windows or Linux or BSD only")
- def test_cpu_affinity_set(self):
- affinity = psutil.Process().cpu_affinity()
- self.execute('cpu_affinity', affinity)
- if not TRAVIS:
- self.execute_w_exc(ValueError, 'cpu_affinity', [-1])
-
- @skip_if_linux()
- def test_open_files(self):
- safe_remove(TESTFN) # needed after UNIX socket test has run
- with open(TESTFN, 'w'):
- self.execute('open_files')
-
- # OSX implementation is unbelievably slow
- @unittest.skipIf(OSX, "OSX implementation is too slow")
- @skip_if_linux()
- def test_memory_maps(self):
- self.execute('memory_maps')
-
- @unittest.skipUnless(LINUX, "Linux only")
- @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
- "only available on Linux >= 2.6.36")
- def test_rlimit_get(self):
- self.execute('rlimit', psutil.RLIMIT_NOFILE)
-
- @unittest.skipUnless(LINUX, "Linux only")
- @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
- "only available on Linux >= 2.6.36")
- def test_rlimit_set(self):
- limit = psutil.Process().rlimit(psutil.RLIMIT_NOFILE)
- self.execute('rlimit', psutil.RLIMIT_NOFILE, limit)
- self.execute_w_exc(OSError, 'rlimit', -1)
-
- @skip_if_linux()
- # Windows implementation is based on a single system-wide function
- @unittest.skipIf(WINDOWS, "tested later")
- def test_connections(self):
- def create_socket(family, type):
- sock = socket.socket(family, type)
- sock.bind(('', 0))
- if type == socket.SOCK_STREAM:
- sock.listen(1)
- return sock
-
- socks = []
- socks.append(create_socket(socket.AF_INET, socket.SOCK_STREAM))
- socks.append(create_socket(socket.AF_INET, socket.SOCK_DGRAM))
- if supports_ipv6():
- socks.append(create_socket(socket.AF_INET6, socket.SOCK_STREAM))
- socks.append(create_socket(socket.AF_INET6, socket.SOCK_DGRAM))
- if hasattr(socket, 'AF_UNIX'):
- safe_remove(TESTFN)
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- s.bind(TESTFN)
- s.listen(1)
- socks.append(s)
- kind = 'all'
- # TODO: UNIX sockets are temporarily implemented by parsing
- # 'pfiles' cmd output; we don't want that part of the code to
- # be executed.
- if SUNOS:
- kind = 'inet'
- try:
- self.execute('connections', kind=kind)
- finally:
- for s in socks:
- s.close()
-
-
-p = get_test_subprocess()
-DEAD_PROC = psutil.Process(p.pid)
-DEAD_PROC.kill()
-DEAD_PROC.wait()
-del p
-
-
-class TestProcessObjectLeaksZombie(TestProcessObjectLeaks):
- """Same as above but looks for leaks occurring when dealing with
- zombie processes raising NoSuchProcess exception.
- """
- proc = DEAD_PROC
-
- def call(self, *args, **kwargs):
- try:
- TestProcessObjectLeaks.call(self, *args, **kwargs)
- except psutil.NoSuchProcess:
- pass
-
- if not POSIX:
- def test_kill(self):
- self.execute('kill')
-
- def test_terminate(self):
- self.execute('terminate')
-
- def test_suspend(self):
- self.execute('suspend')
-
- def test_resume(self):
- self.execute('resume')
-
- def test_wait(self):
- self.execute('wait')
-
-
-class TestModuleFunctionsLeaks(Base):
- """Test leaks of psutil module functions."""
-
- def setUp(self):
- gc.collect()
-
- def call(self, function, *args, **kwargs):
- fun = getattr(psutil, function)
- fun(*args, **kwargs)
-
- @skip_if_linux()
- def test_cpu_count_logical(self):
- psutil.cpu_count = psutil._psplatform.cpu_count_logical
- self.execute('cpu_count')
-
- @skip_if_linux()
- def test_cpu_count_physical(self):
- psutil.cpu_count = psutil._psplatform.cpu_count_physical
- self.execute('cpu_count')
-
- @skip_if_linux()
- def test_boot_time(self):
- self.execute('boot_time')
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "not worth being tested on POSIX (pure python)")
- def test_pid_exists(self):
- self.execute('pid_exists', os.getpid())
-
- def test_virtual_memory(self):
- self.execute('virtual_memory')
-
- # TODO: remove this skip when this gets fixed
- @unittest.skipIf(SUNOS,
- "not worth being tested on SUNOS (uses a subprocess)")
- def test_swap_memory(self):
- self.execute('swap_memory')
-
- @skip_if_linux()
- def test_cpu_times(self):
- self.execute('cpu_times')
-
- @skip_if_linux()
- def test_per_cpu_times(self):
- self.execute('cpu_times', percpu=True)
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "not worth being tested on POSIX (pure python)")
- def test_disk_usage(self):
- self.execute('disk_usage', '.')
-
- def test_disk_partitions(self):
- self.execute('disk_partitions')
-
- @skip_if_linux()
- def test_net_io_counters(self):
- self.execute('net_io_counters')
-
- @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
- '/proc/diskstats not available on this Linux version')
- @skip_if_linux()
- def test_disk_io_counters(self):
- self.execute('disk_io_counters')
-
- # XXX - on Windows this produces a false positive
- @unittest.skipIf(WINDOWS, "XXX produces a false positive on Windows")
- def test_users(self):
- self.execute('users')
-
- @unittest.skipIf(LINUX,
- "not worth being tested on Linux (pure python)")
- def test_net_connections(self):
- self.execute('net_connections')
-
- def test_net_if_addrs(self):
- self.execute('net_if_addrs')
-
- @unittest.skipIf(TRAVIS, "EPERM on travis")
- def test_net_if_stats(self):
- self.execute('net_if_stats')
-
-
-def main():
- test_suite = unittest.TestSuite()
- tests = [TestProcessObjectLeaksZombie,
- TestProcessObjectLeaks,
- TestModuleFunctionsLeaks]
- for test in tests:
- test_suite.addTest(unittest.makeSuite(test))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/test/test_psutil.py b/python/psutil/test/test_psutil.py
deleted file mode 100644
index 3b2e3587a..000000000
--- a/python/psutil/test/test_psutil.py
+++ /dev/null
@@ -1,3013 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-psutil test suite. Run it with:
-$ make test
-
-If you're on Python < 2.7 unittest2 module must be installed first:
-https://pypi.python.org/pypi/unittest2
-"""
-
-from __future__ import division
-
-import ast
-import atexit
-import collections
-import contextlib
-import datetime
-import errno
-import functools
-import imp
-import json
-import os
-import pickle
-import pprint
-import re
-import select
-import shutil
-import signal
-import socket
-import stat
-import subprocess
-import sys
-import tempfile
-import textwrap
-import threading
-import time
-import traceback
-import types
-import warnings
-from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
-try:
- import ipaddress # python >= 3.3
-except ImportError:
- ipaddress = None
-try:
- from unittest import mock # py3
-except ImportError:
- import mock # requires "pip install mock"
-
-import psutil
-from psutil._compat import PY3, callable, long, unicode
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest # https://pypi.python.org/pypi/unittest2
-else:
- import unittest
-if sys.version_info >= (3, 4):
- import enum
-else:
- enum = None
-
-
-# ===================================================================
-# --- Constants
-# ===================================================================
-
-# conf for retry_before_failing() decorator
-NO_RETRIES = 10
-# bytes tolerance for OS memory related tests
-TOLERANCE = 500 * 1024 # 500KB
-# the timeout used in functions which have to wait
-GLOBAL_TIMEOUT = 3
-
-AF_INET6 = getattr(socket, "AF_INET6")
-AF_UNIX = getattr(socket, "AF_UNIX", None)
-PYTHON = os.path.realpath(sys.executable)
-DEVNULL = open(os.devnull, 'r+')
-TESTFN = os.path.join(os.getcwd(), "$testfile")
-TESTFN_UNICODE = TESTFN + "ƒőő"
-TESTFILE_PREFIX = 'psutil-test-suite-'
-if not PY3:
- try:
- TESTFN_UNICODE = unicode(TESTFN_UNICODE, sys.getfilesystemencoding())
- except UnicodeDecodeError:
- TESTFN_UNICODE = TESTFN + "???"
-
-EXAMPLES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
- '..', 'examples'))
-
-POSIX = os.name == 'posix'
-WINDOWS = os.name == 'nt'
-if WINDOWS:
- WIN_VISTA = (6, 0, 0)
-LINUX = sys.platform.startswith("linux")
-OSX = sys.platform.startswith("darwin")
-BSD = sys.platform.startswith("freebsd")
-SUNOS = sys.platform.startswith("sunos")
-VALID_PROC_STATUSES = [getattr(psutil, x) for x in dir(psutil)
- if x.startswith('STATUS_')]
-# whether we're running this test suite on Travis (https://travis-ci.org/)
-TRAVIS = bool(os.environ.get('TRAVIS'))
-# whether we're running this test suite on Appveyor for Windows
-# (http://www.appveyor.com/)
-APPVEYOR = bool(os.environ.get('APPVEYOR'))
-
-if TRAVIS or 'tox' in sys.argv[0]:
- import ipaddress
-if TRAVIS or APPVEYOR:
- GLOBAL_TIMEOUT = GLOBAL_TIMEOUT * 4
-
-
-# ===================================================================
-# --- Utility functions
-# ===================================================================
-
-def cleanup():
- reap_children(search_all=True)
- safe_remove(TESTFN)
- try:
- safe_rmdir(TESTFN_UNICODE)
- except UnicodeEncodeError:
- pass
- for path in _testfiles:
- safe_remove(path)
-
-atexit.register(cleanup)
-atexit.register(lambda: DEVNULL.close())
-
-
-_subprocesses_started = set()
-
-
-def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL,
- stdin=DEVNULL, wait=False):
- """Return a subprocess.Popen object to use in tests.
- By default stdout and stderr are redirected to /dev/null and the
- python interpreter is used as test process.
- If 'wait' is True attemps to make sure the process is in a
- reasonably initialized state.
- """
- if cmd is None:
- pyline = ""
- if wait:
- pyline += "open(r'%s', 'w'); " % TESTFN
- pyline += "import time; time.sleep(60);"
- cmd_ = [PYTHON, "-c", pyline]
- else:
- cmd_ = cmd
- sproc = subprocess.Popen(cmd_, stdout=stdout, stderr=stderr, stdin=stdin)
- if wait:
- if cmd is None:
- stop_at = time.time() + 3
- while stop_at > time.time():
- if os.path.exists(TESTFN):
- break
- time.sleep(0.001)
- else:
- warn("couldn't make sure test file was actually created")
- else:
- wait_for_pid(sproc.pid)
- _subprocesses_started.add(psutil.Process(sproc.pid))
- return sproc
-
-
-_testfiles = []
-
-
-def pyrun(src):
- """Run python code 'src' in a separate interpreter.
- Return interpreter subprocess.
- """
- if PY3:
- src = bytes(src, 'ascii')
- with tempfile.NamedTemporaryFile(
- prefix=TESTFILE_PREFIX, delete=False) as f:
- _testfiles.append(f.name)
- f.write(src)
- f.flush()
- subp = get_test_subprocess([PYTHON, f.name], stdout=None,
- stderr=None)
- wait_for_pid(subp.pid)
- return subp
-
-
-def warn(msg):
- """Raise a warning msg."""
- warnings.warn(msg, UserWarning)
-
-
-def sh(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
- """run cmd in a subprocess and return its output.
- raises RuntimeError on error.
- """
- p = subprocess.Popen(cmdline, shell=True, stdout=stdout, stderr=stderr)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- raise RuntimeError(stderr)
- if stderr:
- warn(stderr)
- if PY3:
- stdout = str(stdout, sys.stdout.encoding)
- return stdout.strip()
-
-
-def which(program):
- """Same as UNIX which command. Return None on command not found."""
- def is_exe(fpath):
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
- fpath, fname = os.path.split(program)
- if fpath:
- if is_exe(program):
- return program
- else:
- for path in os.environ["PATH"].split(os.pathsep):
- exe_file = os.path.join(path, program)
- if is_exe(exe_file):
- return exe_file
- return None
-
-
-if POSIX:
- def get_kernel_version():
- """Return a tuple such as (2, 6, 36)."""
- s = ""
- uname = os.uname()[2]
- for c in uname:
- if c.isdigit() or c == '.':
- s += c
- else:
- break
- if not s:
- raise ValueError("can't parse %r" % uname)
- minor = 0
- micro = 0
- nums = s.split('.')
- major = int(nums[0])
- if len(nums) >= 2:
- minor = int(nums[1])
- if len(nums) >= 3:
- micro = int(nums[2])
- return (major, minor, micro)
-
-
-if LINUX:
- RLIMIT_SUPPORT = get_kernel_version() >= (2, 6, 36)
-else:
- RLIMIT_SUPPORT = False
-
-
-def wait_for_pid(pid, timeout=GLOBAL_TIMEOUT):
- """Wait for pid to show up in the process list then return.
- Used in the test suite to give time the sub process to initialize.
- """
- raise_at = time.time() + timeout
- while True:
- if pid in psutil.pids():
- # give it one more iteration to allow full initialization
- time.sleep(0.01)
- return
- time.sleep(0.0001)
- if time.time() >= raise_at:
- raise RuntimeError("Timed out")
-
-
-def wait_for_file(fname, timeout=GLOBAL_TIMEOUT, delete_file=True):
- """Wait for a file to be written on disk."""
- stop_at = time.time() + 3
- while time.time() < stop_at:
- try:
- with open(fname, "r") as f:
- data = f.read()
- if not data:
- continue
- if delete_file:
- os.remove(fname)
- return data
- except IOError:
- time.sleep(0.001)
- raise RuntimeError("timed out (couldn't read file)")
-
-
-def reap_children(search_all=False):
- """Kill any subprocess started by this test suite and ensure that
- no zombies stick around to hog resources and create problems when
- looking for refleaks.
- """
- global _subprocesses_started
- procs = _subprocesses_started.copy()
- if search_all:
- this_process = psutil.Process()
- for p in this_process.children(recursive=True):
- procs.add(p)
- for p in procs:
- try:
- p.terminate()
- except psutil.NoSuchProcess:
- pass
- gone, alive = psutil.wait_procs(procs, timeout=GLOBAL_TIMEOUT)
- for p in alive:
- warn("couldn't terminate process %s" % p)
- try:
- p.kill()
- except psutil.NoSuchProcess:
- pass
- _, alive = psutil.wait_procs(alive, timeout=GLOBAL_TIMEOUT)
- if alive:
- warn("couldn't not kill processes %s" % str(alive))
- _subprocesses_started = set(alive)
-
-
-def check_ip_address(addr, family):
- """Attempts to check IP address's validity."""
- if enum and PY3:
- assert isinstance(family, enum.IntEnum), family
- if family == AF_INET:
- octs = [int(x) for x in addr.split('.')]
- assert len(octs) == 4, addr
- for num in octs:
- assert 0 <= num <= 255, addr
- if ipaddress:
- if not PY3:
- addr = unicode(addr)
- ipaddress.IPv4Address(addr)
- elif family == AF_INET6:
- assert isinstance(addr, str), addr
- if ipaddress:
- if not PY3:
- addr = unicode(addr)
- ipaddress.IPv6Address(addr)
- elif family == psutil.AF_LINK:
- assert re.match('([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
- else:
- raise ValueError("unknown family %r", family)
-
-
-def check_connection_ntuple(conn):
- """Check validity of a connection namedtuple."""
- valid_conn_states = [getattr(psutil, x) for x in dir(psutil) if
- x.startswith('CONN_')]
- assert conn[0] == conn.fd
- assert conn[1] == conn.family
- assert conn[2] == conn.type
- assert conn[3] == conn.laddr
- assert conn[4] == conn.raddr
- assert conn[5] == conn.status
- assert conn.type in (SOCK_STREAM, SOCK_DGRAM), repr(conn.type)
- assert conn.family in (AF_INET, AF_INET6, AF_UNIX), repr(conn.family)
- assert conn.status in valid_conn_states, conn.status
-
- # check IP address and port sanity
- for addr in (conn.laddr, conn.raddr):
- if not addr:
- continue
- if conn.family in (AF_INET, AF_INET6):
- assert isinstance(addr, tuple), addr
- ip, port = addr
- assert isinstance(port, int), port
- assert 0 <= port <= 65535, port
- check_ip_address(ip, conn.family)
- elif conn.family == AF_UNIX:
- assert isinstance(addr, (str, None)), addr
- else:
- raise ValueError("unknown family %r", conn.family)
-
- if conn.family in (AF_INET, AF_INET6):
- # actually try to bind the local socket; ignore IPv6
- # sockets as their address might be represented as
- # an IPv4-mapped-address (e.g. "::127.0.0.1")
- # and that's rejected by bind()
- if conn.family == AF_INET:
- s = socket.socket(conn.family, conn.type)
- with contextlib.closing(s):
- try:
- s.bind((conn.laddr[0], 0))
- except socket.error as err:
- if err.errno != errno.EADDRNOTAVAIL:
- raise
- elif conn.family == AF_UNIX:
- assert not conn.raddr, repr(conn.raddr)
- assert conn.status == psutil.CONN_NONE, conn.status
-
- if getattr(conn, 'fd', -1) != -1:
- assert conn.fd > 0, conn
- if hasattr(socket, 'fromfd') and not WINDOWS:
- try:
- dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
- except (socket.error, OSError) as err:
- if err.args[0] != errno.EBADF:
- raise
- else:
- with contextlib.closing(dupsock):
- assert dupsock.family == conn.family
- assert dupsock.type == conn.type
-
-
-def safe_remove(file):
- "Convenience function for removing temporary test files"
- try:
- os.remove(file)
- except OSError as err:
- if err.errno != errno.ENOENT:
- # file is being used by another process
- if WINDOWS and isinstance(err, WindowsError) and err.errno == 13:
- return
- raise
-
-
-def safe_rmdir(dir):
- "Convenience function for removing temporary test directories"
- try:
- os.rmdir(dir)
- except OSError as err:
- if err.errno != errno.ENOENT:
- raise
-
-
-def call_until(fun, expr, timeout=GLOBAL_TIMEOUT):
- """Keep calling function for timeout secs and exit if eval()
- expression is True.
- """
- stop_at = time.time() + timeout
- while time.time() < stop_at:
- ret = fun()
- if eval(expr):
- return ret
- time.sleep(0.001)
- raise RuntimeError('timed out (ret=%r)' % ret)
-
-
-def retry_before_failing(ntimes=None):
- """Decorator which runs a test function and retries N times before
- actually failing.
- """
- def decorator(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- for x in range(ntimes or NO_RETRIES):
- try:
- return fun(*args, **kwargs)
- except AssertionError:
- pass
- raise
- return wrapper
- return decorator
-
-
-def skip_on_access_denied(only_if=None):
- """Decorator to Ignore AccessDenied exceptions."""
- def decorator(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except psutil.AccessDenied:
- if only_if is not None:
- if not only_if:
- raise
- msg = "%r was skipped because it raised AccessDenied" \
- % fun.__name__
- raise unittest.SkipTest(msg)
- return wrapper
- return decorator
-
-
-def skip_on_not_implemented(only_if=None):
- """Decorator to Ignore NotImplementedError exceptions."""
- def decorator(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except NotImplementedError:
- if only_if is not None:
- if not only_if:
- raise
- msg = "%r was skipped because it raised NotImplementedError" \
- % fun.__name__
- raise unittest.SkipTest(msg)
- return wrapper
- return decorator
-
-
-def supports_ipv6():
- """Return True if IPv6 is supported on this platform."""
- if not socket.has_ipv6 or not hasattr(socket, "AF_INET6"):
- return False
- sock = None
- try:
- sock = socket.socket(AF_INET6, SOCK_STREAM)
- sock.bind(("::1", 0))
- except (socket.error, socket.gaierror):
- return False
- else:
- return True
- finally:
- if sock is not None:
- sock.close()
-
-
-if WINDOWS:
- def get_winver():
- wv = sys.getwindowsversion()
- if hasattr(wv, 'service_pack_major'): # python >= 2.7
- sp = wv.service_pack_major or 0
- else:
- r = re.search("\s\d$", wv[4])
- if r:
- sp = int(r.group(0))
- else:
- sp = 0
- return (wv[0], wv[1], sp)
-
-
-class ThreadTask(threading.Thread):
- """A thread object used for running process thread tests."""
-
- def __init__(self):
- threading.Thread.__init__(self)
- self._running = False
- self._interval = None
- self._flag = threading.Event()
-
- def __repr__(self):
- name = self.__class__.__name__
- return '<%s running=%s at %#x>' % (name, self._running, id(self))
-
- def start(self, interval=0.001):
- """Start thread and keep it running until an explicit
- stop() request. Polls for shutdown every 'timeout' seconds.
- """
- if self._running:
- raise ValueError("already started")
- self._interval = interval
- threading.Thread.start(self)
- self._flag.wait()
-
- def run(self):
- self._running = True
- self._flag.set()
- while self._running:
- time.sleep(self._interval)
-
- def stop(self):
- """Stop thread execution and and waits until it is stopped."""
- if not self._running:
- raise ValueError("already stopped")
- self._running = False
- self.join()
-
-
-# ===================================================================
-# --- System-related API tests
-# ===================================================================
-
-class TestSystemAPIs(unittest.TestCase):
- """Tests for system-related APIs."""
-
- def setUp(self):
- safe_remove(TESTFN)
-
- def tearDown(self):
- reap_children()
-
- def test_process_iter(self):
- self.assertIn(os.getpid(), [x.pid for x in psutil.process_iter()])
- sproc = get_test_subprocess()
- self.assertIn(sproc.pid, [x.pid for x in psutil.process_iter()])
- p = psutil.Process(sproc.pid)
- p.kill()
- p.wait()
- self.assertNotIn(sproc.pid, [x.pid for x in psutil.process_iter()])
-
- def test_wait_procs(self):
- def callback(p):
- l.append(p.pid)
-
- l = []
- sproc1 = get_test_subprocess()
- sproc2 = get_test_subprocess()
- sproc3 = get_test_subprocess()
- procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
- self.assertRaises(ValueError, psutil.wait_procs, procs, timeout=-1)
- self.assertRaises(TypeError, psutil.wait_procs, procs, callback=1)
- t = time.time()
- gone, alive = psutil.wait_procs(procs, timeout=0.01, callback=callback)
-
- self.assertLess(time.time() - t, 0.5)
- self.assertEqual(gone, [])
- self.assertEqual(len(alive), 3)
- self.assertEqual(l, [])
- for p in alive:
- self.assertFalse(hasattr(p, 'returncode'))
-
- @retry_before_failing(30)
- def test(procs, callback):
- gone, alive = psutil.wait_procs(procs, timeout=0.03,
- callback=callback)
- self.assertEqual(len(gone), 1)
- self.assertEqual(len(alive), 2)
- return gone, alive
-
- sproc3.terminate()
- gone, alive = test(procs, callback)
- self.assertIn(sproc3.pid, [x.pid for x in gone])
- if POSIX:
- self.assertEqual(gone.pop().returncode, signal.SIGTERM)
- else:
- self.assertEqual(gone.pop().returncode, 1)
- self.assertEqual(l, [sproc3.pid])
- for p in alive:
- self.assertFalse(hasattr(p, 'returncode'))
-
- @retry_before_failing(30)
- def test(procs, callback):
- gone, alive = psutil.wait_procs(procs, timeout=0.03,
- callback=callback)
- self.assertEqual(len(gone), 3)
- self.assertEqual(len(alive), 0)
- return gone, alive
-
- sproc1.terminate()
- sproc2.terminate()
- gone, alive = test(procs, callback)
- self.assertEqual(set(l), set([sproc1.pid, sproc2.pid, sproc3.pid]))
- for p in gone:
- self.assertTrue(hasattr(p, 'returncode'))
-
- def test_wait_procs_no_timeout(self):
- sproc1 = get_test_subprocess()
- sproc2 = get_test_subprocess()
- sproc3 = get_test_subprocess()
- procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
- for p in procs:
- p.terminate()
- gone, alive = psutil.wait_procs(procs)
-
- def test_boot_time(self):
- bt = psutil.boot_time()
- self.assertIsInstance(bt, float)
- self.assertGreater(bt, 0)
- self.assertLess(bt, time.time())
-
- @unittest.skipUnless(POSIX, 'posix only')
- def test_PAGESIZE(self):
- # pagesize is used internally to perform different calculations
- # and it's determined by using SC_PAGE_SIZE; make sure
- # getpagesize() returns the same value.
- import resource
- self.assertEqual(os.sysconf("SC_PAGE_SIZE"), resource.getpagesize())
-
- def test_virtual_memory(self):
- mem = psutil.virtual_memory()
- assert mem.total > 0, mem
- assert mem.available > 0, mem
- assert 0 <= mem.percent <= 100, mem
- assert mem.used > 0, mem
- assert mem.free >= 0, mem
- for name in mem._fields:
- value = getattr(mem, name)
- if name != 'percent':
- self.assertIsInstance(value, (int, long))
- if name != 'total':
- if not value >= 0:
- self.fail("%r < 0 (%s)" % (name, value))
- if value > mem.total:
- self.fail("%r > total (total=%s, %s=%s)"
- % (name, mem.total, name, value))
-
- def test_swap_memory(self):
- mem = psutil.swap_memory()
- assert mem.total >= 0, mem
- assert mem.used >= 0, mem
- if mem.total > 0:
- # likely a system with no swap partition
- assert mem.free > 0, mem
- else:
- assert mem.free == 0, mem
- assert 0 <= mem.percent <= 100, mem
- assert mem.sin >= 0, mem
- assert mem.sout >= 0, mem
-
- def test_pid_exists(self):
- sproc = get_test_subprocess(wait=True)
- self.assertTrue(psutil.pid_exists(sproc.pid))
- p = psutil.Process(sproc.pid)
- p.kill()
- p.wait()
- self.assertFalse(psutil.pid_exists(sproc.pid))
- self.assertFalse(psutil.pid_exists(-1))
- self.assertEqual(psutil.pid_exists(0), 0 in psutil.pids())
- # pid 0
- psutil.pid_exists(0) == 0 in psutil.pids()
-
- def test_pid_exists_2(self):
- reap_children()
- pids = psutil.pids()
- for pid in pids:
- try:
- assert psutil.pid_exists(pid)
- except AssertionError:
- # in case the process disappeared in meantime fail only
- # if it is no longer in psutil.pids()
- time.sleep(.1)
- if pid in psutil.pids():
- self.fail(pid)
- pids = range(max(pids) + 5000, max(pids) + 6000)
- for pid in pids:
- self.assertFalse(psutil.pid_exists(pid), msg=pid)
-
- def test_pids(self):
- plist = [x.pid for x in psutil.process_iter()]
- pidlist = psutil.pids()
- self.assertEqual(plist.sort(), pidlist.sort())
- # make sure every pid is unique
- self.assertEqual(len(pidlist), len(set(pidlist)))
-
- def test_test(self):
- # test for psutil.test() function
- stdout = sys.stdout
- sys.stdout = DEVNULL
- try:
- psutil.test()
- finally:
- sys.stdout = stdout
-
- def test_cpu_count(self):
- logical = psutil.cpu_count()
- self.assertEqual(logical, len(psutil.cpu_times(percpu=True)))
- self.assertGreaterEqual(logical, 1)
- #
- if LINUX:
- with open("/proc/cpuinfo") as fd:
- cpuinfo_data = fd.read()
- if "physical id" not in cpuinfo_data:
- raise unittest.SkipTest("cpuinfo doesn't include physical id")
- physical = psutil.cpu_count(logical=False)
- self.assertGreaterEqual(physical, 1)
- self.assertGreaterEqual(logical, physical)
-
- def test_sys_cpu_times(self):
- total = 0
- times = psutil.cpu_times()
- sum(times)
- for cp_time in times:
- self.assertIsInstance(cp_time, float)
- self.assertGreaterEqual(cp_time, 0.0)
- total += cp_time
- self.assertEqual(total, sum(times))
- str(times)
- if not WINDOWS:
- # CPU times are always supposed to increase over time or
- # remain the same but never go backwards, see:
- # https://github.com/giampaolo/psutil/issues/392
- last = psutil.cpu_times()
- for x in range(100):
- new = psutil.cpu_times()
- for field in new._fields:
- new_t = getattr(new, field)
- last_t = getattr(last, field)
- self.assertGreaterEqual(new_t, last_t,
- msg="%s %s" % (new_t, last_t))
- last = new
-
- def test_sys_cpu_times2(self):
- t1 = sum(psutil.cpu_times())
- time.sleep(0.1)
- t2 = sum(psutil.cpu_times())
- difference = t2 - t1
- if not difference >= 0.05:
- self.fail("difference %s" % difference)
-
- def test_sys_per_cpu_times(self):
- for times in psutil.cpu_times(percpu=True):
- total = 0
- sum(times)
- for cp_time in times:
- self.assertIsInstance(cp_time, float)
- self.assertGreaterEqual(cp_time, 0.0)
- total += cp_time
- self.assertEqual(total, sum(times))
- str(times)
- self.assertEqual(len(psutil.cpu_times(percpu=True)[0]),
- len(psutil.cpu_times(percpu=False)))
-
- # Note: in theory CPU times are always supposed to increase over
- # time or remain the same but never go backwards. In practice
- # sometimes this is not the case.
- # This issue seemd to be afflict Windows:
- # https://github.com/giampaolo/psutil/issues/392
- # ...but it turns out also Linux (rarely) behaves the same.
- # last = psutil.cpu_times(percpu=True)
- # for x in range(100):
- # new = psutil.cpu_times(percpu=True)
- # for index in range(len(new)):
- # newcpu = new[index]
- # lastcpu = last[index]
- # for field in newcpu._fields:
- # new_t = getattr(newcpu, field)
- # last_t = getattr(lastcpu, field)
- # self.assertGreaterEqual(
- # new_t, last_t, msg="%s %s" % (lastcpu, newcpu))
- # last = new
-
- def test_sys_per_cpu_times_2(self):
- tot1 = psutil.cpu_times(percpu=True)
- stop_at = time.time() + 0.1
- while True:
- if time.time() >= stop_at:
- break
- tot2 = psutil.cpu_times(percpu=True)
- for t1, t2 in zip(tot1, tot2):
- t1, t2 = sum(t1), sum(t2)
- difference = t2 - t1
- if difference >= 0.05:
- return
- self.fail()
-
- def _test_cpu_percent(self, percent, last_ret, new_ret):
- try:
- self.assertIsInstance(percent, float)
- self.assertGreaterEqual(percent, 0.0)
- self.assertIsNot(percent, -0.0)
- self.assertLessEqual(percent, 100.0 * psutil.cpu_count())
- except AssertionError as err:
- raise AssertionError("\n%s\nlast=%s\nnew=%s" % (
- err, pprint.pformat(last_ret), pprint.pformat(new_ret)))
-
- def test_sys_cpu_percent(self):
- last = psutil.cpu_percent(interval=0.001)
- for x in range(100):
- new = psutil.cpu_percent(interval=None)
- self._test_cpu_percent(new, last, new)
- last = new
-
- def test_sys_per_cpu_percent(self):
- last = psutil.cpu_percent(interval=0.001, percpu=True)
- self.assertEqual(len(last), psutil.cpu_count())
- for x in range(100):
- new = psutil.cpu_percent(interval=None, percpu=True)
- for percent in new:
- self._test_cpu_percent(percent, last, new)
- last = new
-
- def test_sys_cpu_times_percent(self):
- last = psutil.cpu_times_percent(interval=0.001)
- for x in range(100):
- new = psutil.cpu_times_percent(interval=None)
- for percent in new:
- self._test_cpu_percent(percent, last, new)
- self._test_cpu_percent(sum(new), last, new)
- last = new
-
- def test_sys_per_cpu_times_percent(self):
- last = psutil.cpu_times_percent(interval=0.001, percpu=True)
- self.assertEqual(len(last), psutil.cpu_count())
- for x in range(100):
- new = psutil.cpu_times_percent(interval=None, percpu=True)
- for cpu in new:
- for percent in cpu:
- self._test_cpu_percent(percent, last, new)
- self._test_cpu_percent(sum(cpu), last, new)
- last = new
-
- def test_sys_per_cpu_times_percent_negative(self):
- # see: https://github.com/giampaolo/psutil/issues/645
- psutil.cpu_times_percent(percpu=True)
- zero_times = [x._make([0 for x in range(len(x._fields))])
- for x in psutil.cpu_times(percpu=True)]
- with mock.patch('psutil.cpu_times', return_value=zero_times):
- for cpu in psutil.cpu_times_percent(percpu=True):
- for percent in cpu:
- self._test_cpu_percent(percent, None, None)
-
- @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
- "os.statvfs() function not available on this platform")
- def test_disk_usage(self):
- usage = psutil.disk_usage(os.getcwd())
- assert usage.total > 0, usage
- assert usage.used > 0, usage
- assert usage.free > 0, usage
- assert usage.total > usage.used, usage
- assert usage.total > usage.free, usage
- assert 0 <= usage.percent <= 100, usage.percent
- if hasattr(shutil, 'disk_usage'):
- # py >= 3.3, see: http://bugs.python.org/issue12442
- shutil_usage = shutil.disk_usage(os.getcwd())
- tolerance = 5 * 1024 * 1024 # 5MB
- self.assertEqual(usage.total, shutil_usage.total)
- self.assertAlmostEqual(usage.free, shutil_usage.free,
- delta=tolerance)
- self.assertAlmostEqual(usage.used, shutil_usage.used,
- delta=tolerance)
-
- # if path does not exist OSError ENOENT is expected across
- # all platforms
- fname = tempfile.mktemp()
- try:
- psutil.disk_usage(fname)
- except OSError as err:
- if err.args[0] != errno.ENOENT:
- raise
- else:
- self.fail("OSError not raised")
-
- @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
- "os.statvfs() function not available on this platform")
- def test_disk_usage_unicode(self):
- # see: https://github.com/giampaolo/psutil/issues/416
- # XXX this test is not really reliable as it always fails on
- # Python 3.X (2.X is fine)
- try:
- safe_rmdir(TESTFN_UNICODE)
- os.mkdir(TESTFN_UNICODE)
- psutil.disk_usage(TESTFN_UNICODE)
- safe_rmdir(TESTFN_UNICODE)
- except UnicodeEncodeError:
- pass
-
- @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
- "os.statvfs() function not available on this platform")
- @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
- def test_disk_partitions(self):
- # all = False
- ls = psutil.disk_partitions(all=False)
- # on travis we get:
- # self.assertEqual(p.cpu_affinity(), [n])
- # AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, 7,... != [0]
- self.assertTrue(ls, msg=ls)
- for disk in ls:
- if WINDOWS and 'cdrom' in disk.opts:
- continue
- if not POSIX:
- assert os.path.exists(disk.device), disk
- else:
- # we cannot make any assumption about this, see:
- # http://goo.gl/p9c43
- disk.device
- if SUNOS:
- # on solaris apparently mount points can also be files
- assert os.path.exists(disk.mountpoint), disk
- else:
- assert os.path.isdir(disk.mountpoint), disk
- assert disk.fstype, disk
- self.assertIsInstance(disk.opts, str)
-
- # all = True
- ls = psutil.disk_partitions(all=True)
- self.assertTrue(ls, msg=ls)
- for disk in psutil.disk_partitions(all=True):
- if not WINDOWS:
- try:
- os.stat(disk.mountpoint)
- except OSError as err:
- # http://mail.python.org/pipermail/python-dev/
- # 2012-June/120787.html
- if err.errno not in (errno.EPERM, errno.EACCES):
- raise
- else:
- if SUNOS:
- # on solaris apparently mount points can also be files
- assert os.path.exists(disk.mountpoint), disk
- else:
- assert os.path.isdir(disk.mountpoint), disk
- self.assertIsInstance(disk.fstype, str)
- self.assertIsInstance(disk.opts, str)
-
- def find_mount_point(path):
- path = os.path.abspath(path)
- while not os.path.ismount(path):
- path = os.path.dirname(path)
- return path
-
- mount = find_mount_point(__file__)
- mounts = [x.mountpoint for x in psutil.disk_partitions(all=True)]
- self.assertIn(mount, mounts)
- psutil.disk_usage(mount)
-
- @skip_on_access_denied()
- def test_net_connections(self):
- def check(cons, families, types_):
- for conn in cons:
- self.assertIn(conn.family, families, msg=conn)
- if conn.family != getattr(socket, 'AF_UNIX', object()):
- self.assertIn(conn.type, types_, msg=conn)
-
- from psutil._common import conn_tmap
- for kind, groups in conn_tmap.items():
- if SUNOS and kind == 'unix':
- continue
- families, types_ = groups
- cons = psutil.net_connections(kind)
- self.assertEqual(len(cons), len(set(cons)))
- check(cons, families, types_)
-
- def test_net_io_counters(self):
- def check_ntuple(nt):
- self.assertEqual(nt[0], nt.bytes_sent)
- self.assertEqual(nt[1], nt.bytes_recv)
- self.assertEqual(nt[2], nt.packets_sent)
- self.assertEqual(nt[3], nt.packets_recv)
- self.assertEqual(nt[4], nt.errin)
- self.assertEqual(nt[5], nt.errout)
- self.assertEqual(nt[6], nt.dropin)
- self.assertEqual(nt[7], nt.dropout)
- assert nt.bytes_sent >= 0, nt
- assert nt.bytes_recv >= 0, nt
- assert nt.packets_sent >= 0, nt
- assert nt.packets_recv >= 0, nt
- assert nt.errin >= 0, nt
- assert nt.errout >= 0, nt
- assert nt.dropin >= 0, nt
- assert nt.dropout >= 0, nt
-
- ret = psutil.net_io_counters(pernic=False)
- check_ntuple(ret)
- ret = psutil.net_io_counters(pernic=True)
- self.assertNotEqual(ret, [])
- for key in ret:
- self.assertTrue(key)
- check_ntuple(ret[key])
-
- def test_net_if_addrs(self):
- nics = psutil.net_if_addrs()
- assert nics, nics
-
- # Not reliable on all platforms (net_if_addrs() reports more
- # interfaces).
- # self.assertEqual(sorted(nics.keys()),
- # sorted(psutil.net_io_counters(pernic=True).keys()))
-
- families = set([socket.AF_INET, AF_INET6, psutil.AF_LINK])
- for nic, addrs in nics.items():
- self.assertEqual(len(set(addrs)), len(addrs))
- for addr in addrs:
- self.assertIsInstance(addr.family, int)
- self.assertIsInstance(addr.address, str)
- self.assertIsInstance(addr.netmask, (str, type(None)))
- self.assertIsInstance(addr.broadcast, (str, type(None)))
- self.assertIn(addr.family, families)
- if sys.version_info >= (3, 4):
- self.assertIsInstance(addr.family, enum.IntEnum)
- if addr.family == socket.AF_INET:
- s = socket.socket(addr.family)
- with contextlib.closing(s):
- s.bind((addr.address, 0))
- elif addr.family == socket.AF_INET6:
- info = socket.getaddrinfo(
- addr.address, 0, socket.AF_INET6, socket.SOCK_STREAM,
- 0, socket.AI_PASSIVE)[0]
- af, socktype, proto, canonname, sa = info
- s = socket.socket(af, socktype, proto)
- with contextlib.closing(s):
- s.bind(sa)
- for ip in (addr.address, addr.netmask, addr.broadcast):
- if ip is not None:
- # TODO: skip AF_INET6 for now because I get:
- # AddressValueError: Only hex digits permitted in
- # u'c6f3%lxcbr0' in u'fe80::c8e0:fff:fe54:c6f3%lxcbr0'
- if addr.family != AF_INET6:
- check_ip_address(ip, addr.family)
-
- if BSD or OSX or SUNOS:
- if hasattr(socket, "AF_LINK"):
- self.assertEqual(psutil.AF_LINK, socket.AF_LINK)
- elif LINUX:
- self.assertEqual(psutil.AF_LINK, socket.AF_PACKET)
- elif WINDOWS:
- self.assertEqual(psutil.AF_LINK, -1)
-
- @unittest.skipIf(TRAVIS, "EPERM on travis")
- def test_net_if_stats(self):
- nics = psutil.net_if_stats()
- assert nics, nics
- all_duplexes = (psutil.NIC_DUPLEX_FULL,
- psutil.NIC_DUPLEX_HALF,
- psutil.NIC_DUPLEX_UNKNOWN)
- for nic, stats in nics.items():
- isup, duplex, speed, mtu = stats
- self.assertIsInstance(isup, bool)
- self.assertIn(duplex, all_duplexes)
- self.assertIn(duplex, all_duplexes)
- self.assertGreaterEqual(speed, 0)
- self.assertGreaterEqual(mtu, 0)
-
- @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
- '/proc/diskstats not available on this linux version')
- @unittest.skipIf(APPVEYOR,
- "can't find any physical disk on Appveyor")
- def test_disk_io_counters(self):
- def check_ntuple(nt):
- self.assertEqual(nt[0], nt.read_count)
- self.assertEqual(nt[1], nt.write_count)
- self.assertEqual(nt[2], nt.read_bytes)
- self.assertEqual(nt[3], nt.write_bytes)
- self.assertEqual(nt[4], nt.read_time)
- self.assertEqual(nt[5], nt.write_time)
- assert nt.read_count >= 0, nt
- assert nt.write_count >= 0, nt
- assert nt.read_bytes >= 0, nt
- assert nt.write_bytes >= 0, nt
- assert nt.read_time >= 0, nt
- assert nt.write_time >= 0, nt
-
- ret = psutil.disk_io_counters(perdisk=False)
- check_ntuple(ret)
- ret = psutil.disk_io_counters(perdisk=True)
- # make sure there are no duplicates
- self.assertEqual(len(ret), len(set(ret)))
- for key in ret:
- assert key, key
- check_ntuple(ret[key])
- if LINUX and key[-1].isdigit():
- # if 'sda1' is listed 'sda' shouldn't, see:
- # https://github.com/giampaolo/psutil/issues/338
- while key[-1].isdigit():
- key = key[:-1]
- self.assertNotIn(key, ret.keys())
-
- def test_users(self):
- users = psutil.users()
- if not APPVEYOR:
- self.assertNotEqual(users, [])
- for user in users:
- assert user.name, user
- user.terminal
- user.host
- assert user.started > 0.0, user
- datetime.datetime.fromtimestamp(user.started)
-
-
-# ===================================================================
-# --- psutil.Process class tests
-# ===================================================================
-
-class TestProcess(unittest.TestCase):
- """Tests for psutil.Process class."""
-
- def setUp(self):
- safe_remove(TESTFN)
-
- def tearDown(self):
- reap_children()
-
- def test_pid(self):
- self.assertEqual(psutil.Process().pid, os.getpid())
- sproc = get_test_subprocess()
- self.assertEqual(psutil.Process(sproc.pid).pid, sproc.pid)
-
- def test_kill(self):
- sproc = get_test_subprocess(wait=True)
- test_pid = sproc.pid
- p = psutil.Process(test_pid)
- p.kill()
- sig = p.wait()
- self.assertFalse(psutil.pid_exists(test_pid))
- if POSIX:
- self.assertEqual(sig, signal.SIGKILL)
-
- def test_terminate(self):
- sproc = get_test_subprocess(wait=True)
- test_pid = sproc.pid
- p = psutil.Process(test_pid)
- p.terminate()
- sig = p.wait()
- self.assertFalse(psutil.pid_exists(test_pid))
- if POSIX:
- self.assertEqual(sig, signal.SIGTERM)
-
- def test_send_signal(self):
- sig = signal.SIGKILL if POSIX else signal.SIGTERM
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- exit_sig = p.wait()
- self.assertFalse(psutil.pid_exists(p.pid))
- if POSIX:
- self.assertEqual(exit_sig, sig)
- #
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- with mock.patch('psutil.os.kill',
- side_effect=OSError(errno.ESRCH, "")) as fun:
- with self.assertRaises(psutil.NoSuchProcess):
- p.send_signal(sig)
- assert fun.called
- #
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- with mock.patch('psutil.os.kill',
- side_effect=OSError(errno.EPERM, "")) as fun:
- with self.assertRaises(psutil.AccessDenied):
- p.send_signal(sig)
- assert fun.called
-
- def test_wait(self):
- # check exit code signal
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.kill()
- code = p.wait()
- if POSIX:
- self.assertEqual(code, signal.SIGKILL)
- else:
- self.assertEqual(code, 0)
- self.assertFalse(p.is_running())
-
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.terminate()
- code = p.wait()
- if POSIX:
- self.assertEqual(code, signal.SIGTERM)
- else:
- self.assertEqual(code, 0)
- self.assertFalse(p.is_running())
-
- # check sys.exit() code
- code = "import time, sys; time.sleep(0.01); sys.exit(5);"
- sproc = get_test_subprocess([PYTHON, "-c", code])
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.wait(), 5)
- self.assertFalse(p.is_running())
-
- # Test wait() issued twice.
- # It is not supposed to raise NSP when the process is gone.
- # On UNIX this should return None, on Windows it should keep
- # returning the exit code.
- sproc = get_test_subprocess([PYTHON, "-c", code])
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.wait(), 5)
- self.assertIn(p.wait(), (5, None))
-
- # test timeout
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.name()
- self.assertRaises(psutil.TimeoutExpired, p.wait, 0.01)
-
- # timeout < 0 not allowed
- self.assertRaises(ValueError, p.wait, -1)
-
- # XXX why is this skipped on Windows?
- @unittest.skipUnless(POSIX, 'skipped on Windows')
- def test_wait_non_children(self):
- # test wait() against processes which are not our children
- code = "import sys;"
- code += "from subprocess import Popen, PIPE;"
- code += "cmd = ['%s', '-c', 'import time; time.sleep(60)'];" % PYTHON
- code += "sp = Popen(cmd, stdout=PIPE);"
- code += "sys.stdout.write(str(sp.pid));"
- sproc = get_test_subprocess([PYTHON, "-c", code],
- stdout=subprocess.PIPE)
- grandson_pid = int(sproc.stdout.read())
- grandson_proc = psutil.Process(grandson_pid)
- try:
- self.assertRaises(psutil.TimeoutExpired, grandson_proc.wait, 0.01)
- grandson_proc.kill()
- ret = grandson_proc.wait()
- self.assertEqual(ret, None)
- finally:
- if grandson_proc.is_running():
- grandson_proc.kill()
- grandson_proc.wait()
-
- def test_wait_timeout_0(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertRaises(psutil.TimeoutExpired, p.wait, 0)
- p.kill()
- stop_at = time.time() + 2
- while True:
- try:
- code = p.wait(0)
- except psutil.TimeoutExpired:
- if time.time() >= stop_at:
- raise
- else:
- break
- if POSIX:
- self.assertEqual(code, signal.SIGKILL)
- else:
- self.assertEqual(code, 0)
- self.assertFalse(p.is_running())
-
- def test_cpu_percent(self):
- p = psutil.Process()
- p.cpu_percent(interval=0.001)
- p.cpu_percent(interval=0.001)
- for x in range(100):
- percent = p.cpu_percent(interval=None)
- self.assertIsInstance(percent, float)
- self.assertGreaterEqual(percent, 0.0)
- if not POSIX:
- self.assertLessEqual(percent, 100.0)
- else:
- self.assertGreaterEqual(percent, 0.0)
-
- def test_cpu_times(self):
- times = psutil.Process().cpu_times()
- assert (times.user > 0.0) or (times.system > 0.0), times
- # make sure returned values can be pretty printed with strftime
- time.strftime("%H:%M:%S", time.localtime(times.user))
- time.strftime("%H:%M:%S", time.localtime(times.system))
-
- # Test Process.cpu_times() against os.times()
- # os.times() is broken on Python 2.6
- # http://bugs.python.org/issue1040026
- # XXX fails on OSX: not sure if it's for os.times(). We should
- # try this with Python 2.7 and re-enable the test.
-
- @unittest.skipUnless(sys.version_info > (2, 6, 1) and not OSX,
- 'os.times() is not reliable on this Python version')
- def test_cpu_times2(self):
- user_time, kernel_time = psutil.Process().cpu_times()
- utime, ktime = os.times()[:2]
-
- # Use os.times()[:2] as base values to compare our results
- # using a tolerance of +/- 0.1 seconds.
- # It will fail if the difference between the values is > 0.1s.
- if (max([user_time, utime]) - min([user_time, utime])) > 0.1:
- self.fail("expected: %s, found: %s" % (utime, user_time))
-
- if (max([kernel_time, ktime]) - min([kernel_time, ktime])) > 0.1:
- self.fail("expected: %s, found: %s" % (ktime, kernel_time))
-
- def test_create_time(self):
- sproc = get_test_subprocess(wait=True)
- now = time.time()
- p = psutil.Process(sproc.pid)
- create_time = p.create_time()
-
- # Use time.time() as base value to compare our result using a
- # tolerance of +/- 1 second.
- # It will fail if the difference between the values is > 2s.
- difference = abs(create_time - now)
- if difference > 2:
- self.fail("expected: %s, found: %s, difference: %s"
- % (now, create_time, difference))
-
- # make sure returned value can be pretty printed with strftime
- time.strftime("%Y %m %d %H:%M:%S", time.localtime(p.create_time()))
-
- @unittest.skipIf(WINDOWS, 'Windows only')
- def test_terminal(self):
- terminal = psutil.Process().terminal()
- if sys.stdin.isatty():
- self.assertEqual(terminal, sh('tty'))
- else:
- assert terminal, repr(terminal)
-
- @unittest.skipUnless(LINUX or BSD or WINDOWS,
- 'not available on this platform')
- @skip_on_not_implemented(only_if=LINUX)
- def test_io_counters(self):
- p = psutil.Process()
- # test reads
- io1 = p.io_counters()
- with open(PYTHON, 'rb') as f:
- f.read()
- io2 = p.io_counters()
- if not BSD:
- assert io2.read_count > io1.read_count, (io1, io2)
- self.assertEqual(io2.write_count, io1.write_count)
- assert io2.read_bytes >= io1.read_bytes, (io1, io2)
- assert io2.write_bytes >= io1.write_bytes, (io1, io2)
- # test writes
- io1 = p.io_counters()
- with tempfile.TemporaryFile(prefix=TESTFILE_PREFIX) as f:
- if PY3:
- f.write(bytes("x" * 1000000, 'ascii'))
- else:
- f.write("x" * 1000000)
- io2 = p.io_counters()
- assert io2.write_count >= io1.write_count, (io1, io2)
- assert io2.write_bytes >= io1.write_bytes, (io1, io2)
- assert io2.read_count >= io1.read_count, (io1, io2)
- assert io2.read_bytes >= io1.read_bytes, (io1, io2)
-
- @unittest.skipUnless(LINUX or (WINDOWS and get_winver() >= WIN_VISTA),
- 'Linux and Windows Vista only')
- @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
- def test_ionice(self):
- if LINUX:
- from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT,
- IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE)
- self.assertEqual(IOPRIO_CLASS_NONE, 0)
- self.assertEqual(IOPRIO_CLASS_RT, 1)
- self.assertEqual(IOPRIO_CLASS_BE, 2)
- self.assertEqual(IOPRIO_CLASS_IDLE, 3)
- p = psutil.Process()
- try:
- p.ionice(2)
- ioclass, value = p.ionice()
- if enum is not None:
- self.assertIsInstance(ioclass, enum.IntEnum)
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 4)
- #
- p.ionice(3)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 3)
- self.assertEqual(value, 0)
- #
- p.ionice(2, 0)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 0)
- p.ionice(2, 7)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 7)
- #
- self.assertRaises(ValueError, p.ionice, 2, 10)
- self.assertRaises(ValueError, p.ionice, 2, -1)
- self.assertRaises(ValueError, p.ionice, 4)
- self.assertRaises(TypeError, p.ionice, 2, "foo")
- self.assertRaisesRegexp(
- ValueError, "can't specify value with IOPRIO_CLASS_NONE",
- p.ionice, psutil.IOPRIO_CLASS_NONE, 1)
- self.assertRaisesRegexp(
- ValueError, "can't specify value with IOPRIO_CLASS_IDLE",
- p.ionice, psutil.IOPRIO_CLASS_IDLE, 1)
- self.assertRaisesRegexp(
- ValueError, "'ioclass' argument must be specified",
- p.ionice, value=1)
- finally:
- p.ionice(IOPRIO_CLASS_NONE)
- else:
- p = psutil.Process()
- original = p.ionice()
- self.assertIsInstance(original, int)
- try:
- value = 0 # very low
- if original == value:
- value = 1 # low
- p.ionice(value)
- self.assertEqual(p.ionice(), value)
- finally:
- p.ionice(original)
- #
- self.assertRaises(ValueError, p.ionice, 3)
- self.assertRaises(TypeError, p.ionice, 2, 1)
-
- @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
- "only available on Linux >= 2.6.36")
- def test_rlimit_get(self):
- import resource
- p = psutil.Process(os.getpid())
- names = [x for x in dir(psutil) if x.startswith('RLIMIT')]
- assert names, names
- for name in names:
- value = getattr(psutil, name)
- self.assertGreaterEqual(value, 0)
- if name in dir(resource):
- self.assertEqual(value, getattr(resource, name))
- self.assertEqual(p.rlimit(value), resource.getrlimit(value))
- else:
- ret = p.rlimit(value)
- self.assertEqual(len(ret), 2)
- self.assertGreaterEqual(ret[0], -1)
- self.assertGreaterEqual(ret[1], -1)
-
- @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
- "only available on Linux >= 2.6.36")
- def test_rlimit_set(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.rlimit(psutil.RLIMIT_NOFILE, (5, 5))
- self.assertEqual(p.rlimit(psutil.RLIMIT_NOFILE), (5, 5))
- # If pid is 0 prlimit() applies to the calling process and
- # we don't want that.
- with self.assertRaises(ValueError):
- psutil._psplatform.Process(0).rlimit(0)
- with self.assertRaises(ValueError):
- p.rlimit(psutil.RLIMIT_NOFILE, (5, 5, 5))
-
- def test_num_threads(self):
- # on certain platforms such as Linux we might test for exact
- # thread number, since we always have with 1 thread per process,
- # but this does not apply across all platforms (OSX, Windows)
- p = psutil.Process()
- step1 = p.num_threads()
-
- thread = ThreadTask()
- thread.start()
- try:
- step2 = p.num_threads()
- self.assertEqual(step2, step1 + 1)
- thread.stop()
- finally:
- if thread._running:
- thread.stop()
-
- @unittest.skipUnless(WINDOWS, 'Windows only')
- def test_num_handles(self):
- # a better test is done later into test/_windows.py
- p = psutil.Process()
- self.assertGreater(p.num_handles(), 0)
-
- def test_threads(self):
- p = psutil.Process()
- step1 = p.threads()
-
- thread = ThreadTask()
- thread.start()
-
- try:
- step2 = p.threads()
- self.assertEqual(len(step2), len(step1) + 1)
- # on Linux, first thread id is supposed to be this process
- if LINUX:
- self.assertEqual(step2[0].id, os.getpid())
- athread = step2[0]
- # test named tuple
- self.assertEqual(athread.id, athread[0])
- self.assertEqual(athread.user_time, athread[1])
- self.assertEqual(athread.system_time, athread[2])
- # test num threads
- thread.stop()
- finally:
- if thread._running:
- thread.stop()
-
- def test_memory_info(self):
- p = psutil.Process()
-
- # step 1 - get a base value to compare our results
- rss1, vms1 = p.memory_info()
- percent1 = p.memory_percent()
- self.assertGreater(rss1, 0)
- self.assertGreater(vms1, 0)
-
- # step 2 - allocate some memory
- memarr = [None] * 1500000
-
- rss2, vms2 = p.memory_info()
- percent2 = p.memory_percent()
- # make sure that the memory usage bumped up
- self.assertGreater(rss2, rss1)
- self.assertGreaterEqual(vms2, vms1) # vms might be equal
- self.assertGreater(percent2, percent1)
- del memarr
-
- # def test_memory_info_ex(self):
- # # tested later in fetch all test suite
-
- def test_memory_maps(self):
- p = psutil.Process()
- maps = p.memory_maps()
- paths = [x for x in maps]
- self.assertEqual(len(paths), len(set(paths)))
- ext_maps = p.memory_maps(grouped=False)
-
- for nt in maps:
- if not nt.path.startswith('['):
- assert os.path.isabs(nt.path), nt.path
- if POSIX:
- assert os.path.exists(nt.path), nt.path
- else:
- # XXX - On Windows we have this strange behavior with
- # 64 bit dlls: they are visible via explorer but cannot
- # be accessed via os.stat() (wtf?).
- if '64' not in os.path.basename(nt.path):
- assert os.path.exists(nt.path), nt.path
- for nt in ext_maps:
- for fname in nt._fields:
- value = getattr(nt, fname)
- if fname == 'path':
- continue
- elif fname in ('addr', 'perms'):
- assert value, value
- else:
- self.assertIsInstance(value, (int, long))
- assert value >= 0, value
-
- def test_memory_percent(self):
- p = psutil.Process()
- self.assertGreater(p.memory_percent(), 0.0)
-
- def test_is_running(self):
- sproc = get_test_subprocess(wait=True)
- p = psutil.Process(sproc.pid)
- assert p.is_running()
- assert p.is_running()
- p.kill()
- p.wait()
- assert not p.is_running()
- assert not p.is_running()
-
- def test_exe(self):
- sproc = get_test_subprocess(wait=True)
- exe = psutil.Process(sproc.pid).exe()
- try:
- self.assertEqual(exe, PYTHON)
- except AssertionError:
- if WINDOWS and len(exe) == len(PYTHON):
- # on Windows we don't care about case sensitivity
- self.assertEqual(exe.lower(), PYTHON.lower())
- else:
- # certain platforms such as BSD are more accurate returning:
- # "/usr/local/bin/python2.7"
- # ...instead of:
- # "/usr/local/bin/python"
- # We do not want to consider this difference in accuracy
- # an error.
- ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
- self.assertEqual(exe.replace(ver, ''), PYTHON.replace(ver, ''))
-
- def test_cmdline(self):
- cmdline = [PYTHON, "-c", "import time; time.sleep(60)"]
- sproc = get_test_subprocess(cmdline, wait=True)
- self.assertEqual(' '.join(psutil.Process(sproc.pid).cmdline()),
- ' '.join(cmdline))
-
- def test_name(self):
- sproc = get_test_subprocess(PYTHON, wait=True)
- name = psutil.Process(sproc.pid).name().lower()
- pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
- assert pyexe.startswith(name), (pyexe, name)
-
- @unittest.skipUnless(POSIX, "posix only")
- # TODO: add support for other compilers
- @unittest.skipUnless(which("gcc"), "gcc not available")
- def test_prog_w_funky_name(self):
- # Test that name(), exe() and cmdline() correctly handle programs
- # with funky chars such as spaces and ")", see:
- # https://github.com/giampaolo/psutil/issues/628
- funky_name = "/tmp/foo bar )"
- _, c_file = tempfile.mkstemp(prefix='psutil-', suffix='.c', dir="/tmp")
- self.addCleanup(lambda: safe_remove(c_file))
- self.addCleanup(lambda: safe_remove(funky_name))
- with open(c_file, "w") as f:
- f.write("void main() { pause(); }")
- subprocess.check_call(["gcc", c_file, "-o", funky_name])
- sproc = get_test_subprocess(
- [funky_name, "arg1", "arg2", "", "arg3", ""])
- p = psutil.Process(sproc.pid)
- # ...in order to try to prevent occasional failures on travis
- wait_for_pid(p.pid)
- self.assertEqual(p.name(), "foo bar )")
- self.assertEqual(p.exe(), "/tmp/foo bar )")
- self.assertEqual(
- p.cmdline(), ["/tmp/foo bar )", "arg1", "arg2", "", "arg3", ""])
-
- @unittest.skipUnless(POSIX, 'posix only')
- def test_uids(self):
- p = psutil.Process()
- real, effective, saved = p.uids()
- # os.getuid() refers to "real" uid
- self.assertEqual(real, os.getuid())
- # os.geteuid() refers to "effective" uid
- self.assertEqual(effective, os.geteuid())
- # no such thing as os.getsuid() ("saved" uid), but starting
- # from python 2.7 we have os.getresuid()[2]
- if hasattr(os, "getresuid"):
- self.assertEqual(saved, os.getresuid()[2])
-
- @unittest.skipUnless(POSIX, 'posix only')
- def test_gids(self):
- p = psutil.Process()
- real, effective, saved = p.gids()
- # os.getuid() refers to "real" uid
- self.assertEqual(real, os.getgid())
- # os.geteuid() refers to "effective" uid
- self.assertEqual(effective, os.getegid())
- # no such thing as os.getsuid() ("saved" uid), but starting
- # from python 2.7 we have os.getresgid()[2]
- if hasattr(os, "getresuid"):
- self.assertEqual(saved, os.getresgid()[2])
-
- def test_nice(self):
- p = psutil.Process()
- self.assertRaises(TypeError, p.nice, "str")
- if WINDOWS:
- try:
- init = p.nice()
- if sys.version_info > (3, 4):
- self.assertIsInstance(init, enum.IntEnum)
- else:
- self.assertIsInstance(init, int)
- self.assertEqual(init, psutil.NORMAL_PRIORITY_CLASS)
- p.nice(psutil.HIGH_PRIORITY_CLASS)
- self.assertEqual(p.nice(), psutil.HIGH_PRIORITY_CLASS)
- p.nice(psutil.NORMAL_PRIORITY_CLASS)
- self.assertEqual(p.nice(), psutil.NORMAL_PRIORITY_CLASS)
- finally:
- p.nice(psutil.NORMAL_PRIORITY_CLASS)
- else:
- try:
- first_nice = p.nice()
- p.nice(1)
- self.assertEqual(p.nice(), 1)
- # going back to previous nice value raises
- # AccessDenied on OSX
- if not OSX:
- p.nice(0)
- self.assertEqual(p.nice(), 0)
- except psutil.AccessDenied:
- pass
- finally:
- try:
- p.nice(first_nice)
- except psutil.AccessDenied:
- pass
-
- def test_status(self):
- p = psutil.Process()
- self.assertEqual(p.status(), psutil.STATUS_RUNNING)
-
- def test_username(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- if POSIX:
- import pwd
- self.assertEqual(p.username(), pwd.getpwuid(os.getuid()).pw_name)
- with mock.patch("psutil.pwd.getpwuid",
- side_effect=KeyError) as fun:
- p.username() == str(p.uids().real)
- assert fun.called
-
- elif WINDOWS and 'USERNAME' in os.environ:
- expected_username = os.environ['USERNAME']
- expected_domain = os.environ['USERDOMAIN']
- domain, username = p.username().split('\\')
- self.assertEqual(domain, expected_domain)
- self.assertEqual(username, expected_username)
- else:
- p.username()
-
- def test_cwd(self):
- sproc = get_test_subprocess(wait=True)
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.cwd(), os.getcwd())
-
- def test_cwd_2(self):
- cmd = [PYTHON, "-c", "import os, time; os.chdir('..'); time.sleep(60)"]
- sproc = get_test_subprocess(cmd, wait=True)
- p = psutil.Process(sproc.pid)
- call_until(p.cwd, "ret == os.path.dirname(os.getcwd())")
-
- @unittest.skipUnless(WINDOWS or LINUX or BSD,
- 'not available on this platform')
- @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
- def test_cpu_affinity(self):
- p = psutil.Process()
- initial = p.cpu_affinity()
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(initial, list(os.sched_getaffinity(p.pid)))
- self.assertEqual(len(initial), len(set(initial)))
- all_cpus = list(range(len(psutil.cpu_percent(percpu=True))))
- # setting on travis doesn't seem to work (always return all
- # CPUs on get):
- # AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, ... != [0]
- for n in all_cpus:
- p.cpu_affinity([n])
- self.assertEqual(p.cpu_affinity(), [n])
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(p.cpu_affinity(),
- list(os.sched_getaffinity(p.pid)))
- #
- p.cpu_affinity(all_cpus)
- self.assertEqual(p.cpu_affinity(), all_cpus)
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(p.cpu_affinity(),
- list(os.sched_getaffinity(p.pid)))
- #
- self.assertRaises(TypeError, p.cpu_affinity, 1)
- p.cpu_affinity(initial)
- # it should work with all iterables, not only lists
- p.cpu_affinity(set(all_cpus))
- p.cpu_affinity(tuple(all_cpus))
- invalid_cpu = [len(psutil.cpu_times(percpu=True)) + 10]
- self.assertRaises(ValueError, p.cpu_affinity, invalid_cpu)
- self.assertRaises(ValueError, p.cpu_affinity, range(10000, 11000))
- self.assertRaises(TypeError, p.cpu_affinity, [0, "1"])
-
- # TODO
- @unittest.skipIf(BSD, "broken on BSD, see #595")
- @unittest.skipIf(APPVEYOR,
- "can't find any process file on Appveyor")
- def test_open_files(self):
- # current process
- p = psutil.Process()
- files = p.open_files()
- self.assertFalse(TESTFN in files)
- with open(TESTFN, 'w'):
- # give the kernel some time to see the new file
- call_until(p.open_files, "len(ret) != %i" % len(files))
- filenames = [x.path for x in p.open_files()]
- self.assertIn(TESTFN, filenames)
- for file in filenames:
- assert os.path.isfile(file), file
-
- # another process
- cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN
- sproc = get_test_subprocess([PYTHON, "-c", cmdline], wait=True)
- p = psutil.Process(sproc.pid)
-
- for x in range(100):
- filenames = [x.path for x in p.open_files()]
- if TESTFN in filenames:
- break
- time.sleep(.01)
- else:
- self.assertIn(TESTFN, filenames)
- for file in filenames:
- assert os.path.isfile(file), file
-
- # TODO
- @unittest.skipIf(BSD, "broken on BSD, see #595")
- @unittest.skipIf(APPVEYOR,
- "can't find any process file on Appveyor")
- def test_open_files2(self):
- # test fd and path fields
- with open(TESTFN, 'w') as fileobj:
- p = psutil.Process()
- for path, fd in p.open_files():
- if path == fileobj.name or fd == fileobj.fileno():
- break
- else:
- self.fail("no file found; files=%s" % repr(p.open_files()))
- self.assertEqual(path, fileobj.name)
- if WINDOWS:
- self.assertEqual(fd, -1)
- else:
- self.assertEqual(fd, fileobj.fileno())
- # test positions
- ntuple = p.open_files()[0]
- self.assertEqual(ntuple[0], ntuple.path)
- self.assertEqual(ntuple[1], ntuple.fd)
- # test file is gone
- self.assertTrue(fileobj.name not in p.open_files())
-
- def compare_proc_sys_cons(self, pid, proc_cons):
- from psutil._common import pconn
- sys_cons = []
- for c in psutil.net_connections(kind='all'):
- if c.pid == pid:
- sys_cons.append(pconn(*c[:-1]))
- if BSD:
- # on BSD all fds are set to -1
- proc_cons = [pconn(*[-1] + list(x[1:])) for x in proc_cons]
- self.assertEqual(sorted(proc_cons), sorted(sys_cons))
-
- @skip_on_access_denied(only_if=OSX)
- def test_connections(self):
- def check_conn(proc, conn, family, type, laddr, raddr, status, kinds):
- all_kinds = ("all", "inet", "inet4", "inet6", "tcp", "tcp4",
- "tcp6", "udp", "udp4", "udp6")
- check_connection_ntuple(conn)
- self.assertEqual(conn.family, family)
- self.assertEqual(conn.type, type)
- self.assertEqual(conn.laddr, laddr)
- self.assertEqual(conn.raddr, raddr)
- self.assertEqual(conn.status, status)
- for kind in all_kinds:
- cons = proc.connections(kind=kind)
- if kind in kinds:
- self.assertNotEqual(cons, [])
- else:
- self.assertEqual(cons, [])
- # compare against system-wide connections
- # XXX Solaris can't retrieve system-wide UNIX
- # sockets.
- if not SUNOS:
- self.compare_proc_sys_cons(proc.pid, [conn])
-
- tcp_template = textwrap.dedent("""
- import socket, time
- s = socket.socket($family, socket.SOCK_STREAM)
- s.bind(('$addr', 0))
- s.listen(1)
- with open('$testfn', 'w') as f:
- f.write(str(s.getsockname()[:2]))
- time.sleep(60)
- """)
-
- udp_template = textwrap.dedent("""
- import socket, time
- s = socket.socket($family, socket.SOCK_DGRAM)
- s.bind(('$addr', 0))
- with open('$testfn', 'w') as f:
- f.write(str(s.getsockname()[:2]))
- time.sleep(60)
- """)
-
- from string import Template
- testfile = os.path.basename(TESTFN)
- tcp4_template = Template(tcp_template).substitute(
- family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
- udp4_template = Template(udp_template).substitute(
- family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
- tcp6_template = Template(tcp_template).substitute(
- family=int(AF_INET6), addr="::1", testfn=testfile)
- udp6_template = Template(udp_template).substitute(
- family=int(AF_INET6), addr="::1", testfn=testfile)
-
- # launch various subprocess instantiating a socket of various
- # families and types to enrich psutil results
- tcp4_proc = pyrun(tcp4_template)
- tcp4_addr = eval(wait_for_file(testfile))
- udp4_proc = pyrun(udp4_template)
- udp4_addr = eval(wait_for_file(testfile))
- if supports_ipv6():
- tcp6_proc = pyrun(tcp6_template)
- tcp6_addr = eval(wait_for_file(testfile))
- udp6_proc = pyrun(udp6_template)
- udp6_addr = eval(wait_for_file(testfile))
- else:
- tcp6_proc = None
- udp6_proc = None
- tcp6_addr = None
- udp6_addr = None
-
- for p in psutil.Process().children():
- cons = p.connections()
- self.assertEqual(len(cons), 1)
- for conn in cons:
- # TCP v4
- if p.pid == tcp4_proc.pid:
- check_conn(p, conn, AF_INET, SOCK_STREAM, tcp4_addr, (),
- psutil.CONN_LISTEN,
- ("all", "inet", "inet4", "tcp", "tcp4"))
- # UDP v4
- elif p.pid == udp4_proc.pid:
- check_conn(p, conn, AF_INET, SOCK_DGRAM, udp4_addr, (),
- psutil.CONN_NONE,
- ("all", "inet", "inet4", "udp", "udp4"))
- # TCP v6
- elif p.pid == getattr(tcp6_proc, "pid", None):
- check_conn(p, conn, AF_INET6, SOCK_STREAM, tcp6_addr, (),
- psutil.CONN_LISTEN,
- ("all", "inet", "inet6", "tcp", "tcp6"))
- # UDP v6
- elif p.pid == getattr(udp6_proc, "pid", None):
- check_conn(p, conn, AF_INET6, SOCK_DGRAM, udp6_addr, (),
- psutil.CONN_NONE,
- ("all", "inet", "inet6", "udp", "udp6"))
-
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'),
- 'AF_UNIX is not supported')
- @skip_on_access_denied(only_if=OSX)
- def test_connections_unix(self):
- def check(type):
- safe_remove(TESTFN)
- sock = socket.socket(AF_UNIX, type)
- with contextlib.closing(sock):
- sock.bind(TESTFN)
- cons = psutil.Process().connections(kind='unix')
- conn = cons[0]
- check_connection_ntuple(conn)
- if conn.fd != -1: # != sunos and windows
- self.assertEqual(conn.fd, sock.fileno())
- self.assertEqual(conn.family, AF_UNIX)
- self.assertEqual(conn.type, type)
- self.assertEqual(conn.laddr, TESTFN)
- if not SUNOS:
- # XXX Solaris can't retrieve system-wide UNIX
- # sockets.
- self.compare_proc_sys_cons(os.getpid(), cons)
-
- check(SOCK_STREAM)
- check(SOCK_DGRAM)
-
- @unittest.skipUnless(hasattr(socket, "fromfd"),
- 'socket.fromfd() is not availble')
- @unittest.skipIf(WINDOWS or SUNOS,
- 'connection fd not available on this platform')
- def test_connection_fromfd(self):
- with contextlib.closing(socket.socket()) as sock:
- sock.bind(('localhost', 0))
- sock.listen(1)
- p = psutil.Process()
- for conn in p.connections():
- if conn.fd == sock.fileno():
- break
- else:
- self.fail("couldn't find socket fd")
- dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
- with contextlib.closing(dupsock):
- self.assertEqual(dupsock.getsockname(), conn.laddr)
- self.assertNotEqual(sock.fileno(), dupsock.fileno())
-
- def test_connection_constants(self):
- ints = []
- strs = []
- for name in dir(psutil):
- if name.startswith('CONN_'):
- num = getattr(psutil, name)
- str_ = str(num)
- assert str_.isupper(), str_
- assert str_ not in strs, str_
- assert num not in ints, num
- ints.append(num)
- strs.append(str_)
- if SUNOS:
- psutil.CONN_IDLE
- psutil.CONN_BOUND
- if WINDOWS:
- psutil.CONN_DELETE_TCB
-
- @unittest.skipUnless(POSIX, 'posix only')
- def test_num_fds(self):
- p = psutil.Process()
- start = p.num_fds()
- file = open(TESTFN, 'w')
- self.addCleanup(file.close)
- self.assertEqual(p.num_fds(), start + 1)
- sock = socket.socket()
- self.addCleanup(sock.close)
- self.assertEqual(p.num_fds(), start + 2)
- file.close()
- sock.close()
- self.assertEqual(p.num_fds(), start)
-
- @skip_on_not_implemented(only_if=LINUX)
- def test_num_ctx_switches(self):
- p = psutil.Process()
- before = sum(p.num_ctx_switches())
- for x in range(500000):
- after = sum(p.num_ctx_switches())
- if after > before:
- return
- self.fail("num ctx switches still the same after 50.000 iterations")
-
- def test_parent_ppid(self):
- this_parent = os.getpid()
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.ppid(), this_parent)
- self.assertEqual(p.parent().pid, this_parent)
- # no other process is supposed to have us as parent
- for p in psutil.process_iter():
- if p.pid == sproc.pid:
- continue
- self.assertTrue(p.ppid() != this_parent)
-
- def test_children(self):
- p = psutil.Process()
- self.assertEqual(p.children(), [])
- self.assertEqual(p.children(recursive=True), [])
- sproc = get_test_subprocess()
- children1 = p.children()
- children2 = p.children(recursive=True)
- for children in (children1, children2):
- self.assertEqual(len(children), 1)
- self.assertEqual(children[0].pid, sproc.pid)
- self.assertEqual(children[0].ppid(), os.getpid())
-
- def test_children_recursive(self):
- # here we create a subprocess which creates another one as in:
- # A (parent) -> B (child) -> C (grandchild)
- s = "import subprocess, os, sys, time;"
- s += "PYTHON = os.path.realpath(sys.executable);"
- s += "cmd = [PYTHON, '-c', 'import time; time.sleep(60);'];"
- s += "subprocess.Popen(cmd);"
- s += "time.sleep(60);"
- get_test_subprocess(cmd=[PYTHON, "-c", s])
- p = psutil.Process()
- self.assertEqual(len(p.children(recursive=False)), 1)
- # give the grandchild some time to start
- stop_at = time.time() + GLOBAL_TIMEOUT
- while time.time() < stop_at:
- children = p.children(recursive=True)
- if len(children) > 1:
- break
- self.assertEqual(len(children), 2)
- self.assertEqual(children[0].ppid(), os.getpid())
- self.assertEqual(children[1].ppid(), children[0].pid)
-
- def test_children_duplicates(self):
- # find the process which has the highest number of children
- table = collections.defaultdict(int)
- for p in psutil.process_iter():
- try:
- table[p.ppid()] += 1
- except psutil.Error:
- pass
- # this is the one, now let's make sure there are no duplicates
- pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
- p = psutil.Process(pid)
- try:
- c = p.children(recursive=True)
- except psutil.AccessDenied: # windows
- pass
- else:
- self.assertEqual(len(c), len(set(c)))
-
- def test_suspend_resume(self):
- sproc = get_test_subprocess(wait=True)
- p = psutil.Process(sproc.pid)
- p.suspend()
- for x in range(100):
- if p.status() == psutil.STATUS_STOPPED:
- break
- time.sleep(0.01)
- p.resume()
- self.assertNotEqual(p.status(), psutil.STATUS_STOPPED)
-
- def test_invalid_pid(self):
- self.assertRaises(TypeError, psutil.Process, "1")
- self.assertRaises(ValueError, psutil.Process, -1)
-
- def test_as_dict(self):
- p = psutil.Process()
- d = p.as_dict(attrs=['exe', 'name'])
- self.assertEqual(sorted(d.keys()), ['exe', 'name'])
-
- p = psutil.Process(min(psutil.pids()))
- d = p.as_dict(attrs=['connections'], ad_value='foo')
- if not isinstance(d['connections'], list):
- self.assertEqual(d['connections'], 'foo')
-
- def test_halfway_terminated_process(self):
- # Test that NoSuchProcess exception gets raised in case the
- # process dies after we create the Process object.
- # Example:
- # >>> proc = Process(1234)
- # >>> time.sleep(2) # time-consuming task, process dies in meantime
- # >>> proc.name()
- # Refers to Issue #15
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.terminate()
- p.wait()
- if WINDOWS:
- wait_for_pid(p.pid)
- self.assertFalse(p.is_running())
- self.assertFalse(p.pid in psutil.pids())
-
- excluded_names = ['pid', 'is_running', 'wait', 'create_time']
- if LINUX and not RLIMIT_SUPPORT:
- excluded_names.append('rlimit')
- for name in dir(p):
- if (name.startswith('_') or
- name in excluded_names):
- continue
- try:
- meth = getattr(p, name)
- # get/set methods
- if name == 'nice':
- if POSIX:
- ret = meth(1)
- else:
- ret = meth(psutil.NORMAL_PRIORITY_CLASS)
- elif name == 'ionice':
- ret = meth()
- ret = meth(2)
- elif name == 'rlimit':
- ret = meth(psutil.RLIMIT_NOFILE)
- ret = meth(psutil.RLIMIT_NOFILE, (5, 5))
- elif name == 'cpu_affinity':
- ret = meth()
- ret = meth([0])
- elif name == 'send_signal':
- ret = meth(signal.SIGTERM)
- else:
- ret = meth()
- except psutil.ZombieProcess:
- self.fail("ZombieProcess for %r was not supposed to happen" %
- name)
- except psutil.NoSuchProcess:
- pass
- except NotImplementedError:
- pass
- else:
- self.fail(
- "NoSuchProcess exception not raised for %r, retval=%s" % (
- name, ret))
-
- @unittest.skipUnless(POSIX, 'posix only')
- def test_zombie_process(self):
- def succeed_or_zombie_p_exc(fun, *args, **kwargs):
- try:
- fun(*args, **kwargs)
- except (psutil.ZombieProcess, psutil.AccessDenied):
- pass
-
- # Note: in this test we'll be creating two sub processes.
- # Both of them are supposed to be freed / killed by
- # reap_children() as they are attributable to 'us'
- # (os.getpid()) via children(recursive=True).
- src = textwrap.dedent("""\
- import os, sys, time, socket, contextlib
- child_pid = os.fork()
- if child_pid > 0:
- time.sleep(3000)
- else:
- # this is the zombie process
- s = socket.socket(socket.AF_UNIX)
- with contextlib.closing(s):
- s.connect('%s')
- if sys.version_info < (3, ):
- pid = str(os.getpid())
- else:
- pid = bytes(str(os.getpid()), 'ascii')
- s.sendall(pid)
- """ % TESTFN)
- with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
- try:
- sock.settimeout(GLOBAL_TIMEOUT)
- sock.bind(TESTFN)
- sock.listen(1)
- pyrun(src)
- conn, _ = sock.accept()
- select.select([conn.fileno()], [], [], GLOBAL_TIMEOUT)
- zpid = int(conn.recv(1024))
- zproc = psutil.Process(zpid)
- call_until(lambda: zproc.status(),
- "ret == psutil.STATUS_ZOMBIE")
- # A zombie process should always be instantiable
- zproc = psutil.Process(zpid)
- # ...and at least its status always be querable
- self.assertEqual(zproc.status(), psutil.STATUS_ZOMBIE)
- # ...and it should be considered 'running'
- self.assertTrue(zproc.is_running())
- # ...and as_dict() shouldn't crash
- zproc.as_dict()
- if hasattr(zproc, "rlimit"):
- succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE)
- succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE,
- (5, 5))
- # set methods
- succeed_or_zombie_p_exc(zproc.parent)
- if hasattr(zproc, 'cpu_affinity'):
- succeed_or_zombie_p_exc(zproc.cpu_affinity, [0])
- succeed_or_zombie_p_exc(zproc.nice, 0)
- if hasattr(zproc, 'ionice'):
- if LINUX:
- succeed_or_zombie_p_exc(zproc.ionice, 2, 0)
- else:
- succeed_or_zombie_p_exc(zproc.ionice, 0) # Windows
- if hasattr(zproc, 'rlimit'):
- succeed_or_zombie_p_exc(zproc.rlimit,
- psutil.RLIMIT_NOFILE, (5, 5))
- succeed_or_zombie_p_exc(zproc.suspend)
- succeed_or_zombie_p_exc(zproc.resume)
- succeed_or_zombie_p_exc(zproc.terminate)
- succeed_or_zombie_p_exc(zproc.kill)
-
- # ...its parent should 'see' it
- # edit: not true on BSD and OSX
- # descendants = [x.pid for x in psutil.Process().children(
- # recursive=True)]
- # self.assertIn(zpid, descendants)
- # XXX should we also assume ppid be usable? Note: this
- # would be an important use case as the only way to get
- # rid of a zombie is to kill its parent.
- # self.assertEqual(zpid.ppid(), os.getpid())
- # ...and all other APIs should be able to deal with it
- self.assertTrue(psutil.pid_exists(zpid))
- self.assertIn(zpid, psutil.pids())
- self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
- psutil._pmap = {}
- self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
- finally:
- reap_children(search_all=True)
-
- def test_pid_0(self):
- # Process(0) is supposed to work on all platforms except Linux
- if 0 not in psutil.pids():
- self.assertRaises(psutil.NoSuchProcess, psutil.Process, 0)
- return
-
- p = psutil.Process(0)
- self.assertTrue(p.name())
-
- if POSIX:
- try:
- self.assertEqual(p.uids().real, 0)
- self.assertEqual(p.gids().real, 0)
- except psutil.AccessDenied:
- pass
-
- self.assertRaisesRegexp(
- ValueError, "preventing sending signal to process with PID 0",
- p.send_signal, signal.SIGTERM)
-
- self.assertIn(p.ppid(), (0, 1))
- # self.assertEqual(p.exe(), "")
- p.cmdline()
- try:
- p.num_threads()
- except psutil.AccessDenied:
- pass
-
- try:
- p.memory_info()
- except psutil.AccessDenied:
- pass
-
- try:
- if POSIX:
- self.assertEqual(p.username(), 'root')
- elif WINDOWS:
- self.assertEqual(p.username(), 'NT AUTHORITY\\SYSTEM')
- else:
- p.username()
- except psutil.AccessDenied:
- pass
-
- self.assertIn(0, psutil.pids())
- self.assertTrue(psutil.pid_exists(0))
-
- def test_Popen(self):
- # Popen class test
- # XXX this test causes a ResourceWarning on Python 3 because
- # psutil.__subproc instance doesn't get propertly freed.
- # Not sure what to do though.
- cmd = [PYTHON, "-c", "import time; time.sleep(60);"]
- proc = psutil.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- try:
- proc.name()
- proc.stdin
- self.assertTrue(hasattr(proc, 'name'))
- self.assertTrue(hasattr(proc, 'stdin'))
- self.assertTrue(dir(proc))
- self.assertRaises(AttributeError, getattr, proc, 'foo')
- finally:
- proc.kill()
- proc.wait()
- self.assertIsNotNone(proc.returncode)
-
-
-# ===================================================================
-# --- Featch all processes test
-# ===================================================================
-
-class TestFetchAllProcesses(unittest.TestCase):
- """Test which iterates over all running processes and performs
- some sanity checks against Process API's returned values.
- """
-
- def setUp(self):
- if POSIX:
- import pwd
- pall = pwd.getpwall()
- self._uids = set([x.pw_uid for x in pall])
- self._usernames = set([x.pw_name for x in pall])
-
- def test_fetch_all(self):
- valid_procs = 0
- excluded_names = set([
- 'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
- 'as_dict', 'cpu_percent', 'parent', 'children', 'pid'])
- if LINUX and not RLIMIT_SUPPORT:
- excluded_names.add('rlimit')
- attrs = []
- for name in dir(psutil.Process):
- if name.startswith("_"):
- continue
- if name in excluded_names:
- continue
- attrs.append(name)
-
- default = object()
- failures = []
- for name in attrs:
- for p in psutil.process_iter():
- ret = default
- try:
- try:
- args = ()
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- if name == 'rlimit':
- args = (psutil.RLIMIT_NOFILE,)
- ret = attr(*args)
- else:
- ret = attr
- valid_procs += 1
- except NotImplementedError:
- msg = "%r was skipped because not implemented" % (
- self.__class__.__name__ + '.test_' + name)
- warn(msg)
- except (psutil.NoSuchProcess, psutil.AccessDenied) as err:
- self.assertEqual(err.pid, p.pid)
- if err.name:
- # make sure exception's name attr is set
- # with the actual process name
- self.assertEqual(err.name, p.name())
- self.assertTrue(str(err))
- self.assertTrue(err.msg)
- else:
- if ret not in (0, 0.0, [], None, ''):
- assert ret, ret
- meth = getattr(self, name)
- meth(ret)
- except Exception as err:
- s = '\n' + '=' * 70 + '\n'
- s += "FAIL: test_%s (proc=%s" % (name, p)
- if ret != default:
- s += ", ret=%s)" % repr(ret)
- s += ')\n'
- s += '-' * 70
- s += "\n%s" % traceback.format_exc()
- s = "\n".join((" " * 4) + i for i in s.splitlines())
- failures.append(s)
- break
-
- if failures:
- self.fail(''.join(failures))
-
- # we should always have a non-empty list, not including PID 0 etc.
- # special cases.
- self.assertTrue(valid_procs > 0)
-
- def cmdline(self, ret):
- pass
-
- def exe(self, ret):
- if not ret:
- self.assertEqual(ret, '')
- else:
- assert os.path.isabs(ret), ret
- # Note: os.stat() may return False even if the file is there
- # hence we skip the test, see:
- # http://stackoverflow.com/questions/3112546/os-path-exists-lies
- if POSIX and os.path.isfile(ret):
- if hasattr(os, 'access') and hasattr(os, "X_OK"):
- # XXX may fail on OSX
- self.assertTrue(os.access(ret, os.X_OK))
-
- def ppid(self, ret):
- self.assertTrue(ret >= 0)
-
- def name(self, ret):
- self.assertIsInstance(ret, (str, unicode))
- self.assertTrue(ret)
-
- def create_time(self, ret):
- self.assertTrue(ret > 0)
- # this can't be taken for granted on all platforms
- # self.assertGreaterEqual(ret, psutil.boot_time())
- # make sure returned value can be pretty printed
- # with strftime
- time.strftime("%Y %m %d %H:%M:%S", time.localtime(ret))
-
- def uids(self, ret):
- for uid in ret:
- self.assertTrue(uid >= 0)
- self.assertIn(uid, self._uids)
-
- def gids(self, ret):
- # note: testing all gids as above seems not to be reliable for
- # gid == 30 (nodoby); not sure why.
- for gid in ret:
- self.assertTrue(gid >= 0)
- # self.assertIn(uid, self.gids
-
- def username(self, ret):
- self.assertTrue(ret)
- if POSIX:
- self.assertIn(ret, self._usernames)
-
- def status(self, ret):
- self.assertTrue(ret != "")
- self.assertTrue(ret != '?')
- self.assertIn(ret, VALID_PROC_STATUSES)
-
- def io_counters(self, ret):
- for field in ret:
- if field != -1:
- self.assertTrue(field >= 0)
-
- def ionice(self, ret):
- if LINUX:
- self.assertTrue(ret.ioclass >= 0)
- self.assertTrue(ret.value >= 0)
- else:
- self.assertTrue(ret >= 0)
- self.assertIn(ret, (0, 1, 2))
-
- def num_threads(self, ret):
- self.assertTrue(ret >= 1)
-
- def threads(self, ret):
- for t in ret:
- self.assertTrue(t.id >= 0)
- self.assertTrue(t.user_time >= 0)
- self.assertTrue(t.system_time >= 0)
-
- def cpu_times(self, ret):
- self.assertTrue(ret.user >= 0)
- self.assertTrue(ret.system >= 0)
-
- def memory_info(self, ret):
- self.assertTrue(ret.rss >= 0)
- self.assertTrue(ret.vms >= 0)
-
- def memory_info_ex(self, ret):
- for name in ret._fields:
- self.assertTrue(getattr(ret, name) >= 0)
- if POSIX and ret.vms != 0:
- # VMS is always supposed to be the highest
- for name in ret._fields:
- if name != 'vms':
- value = getattr(ret, name)
- assert ret.vms > value, ret
- elif WINDOWS:
- assert ret.peak_wset >= ret.wset, ret
- assert ret.peak_paged_pool >= ret.paged_pool, ret
- assert ret.peak_nonpaged_pool >= ret.nonpaged_pool, ret
- assert ret.peak_pagefile >= ret.pagefile, ret
-
- def open_files(self, ret):
- for f in ret:
- if WINDOWS:
- assert f.fd == -1, f
- else:
- self.assertIsInstance(f.fd, int)
- assert os.path.isabs(f.path), f
- assert os.path.isfile(f.path), f
-
- def num_fds(self, ret):
- self.assertTrue(ret >= 0)
-
- def connections(self, ret):
- self.assertEqual(len(ret), len(set(ret)))
- for conn in ret:
- check_connection_ntuple(conn)
-
- def cwd(self, ret):
- if ret is not None: # BSD may return None
- assert os.path.isabs(ret), ret
- try:
- st = os.stat(ret)
- except OSError as err:
- # directory has been removed in mean time
- if err.errno != errno.ENOENT:
- raise
- else:
- self.assertTrue(stat.S_ISDIR(st.st_mode))
-
- def memory_percent(self, ret):
- assert 0 <= ret <= 100, ret
-
- def is_running(self, ret):
- self.assertTrue(ret)
-
- def cpu_affinity(self, ret):
- assert ret != [], ret
-
- def terminal(self, ret):
- if ret is not None:
- assert os.path.isabs(ret), ret
- assert os.path.exists(ret), ret
-
- def memory_maps(self, ret):
- for nt in ret:
- for fname in nt._fields:
- value = getattr(nt, fname)
- if fname == 'path':
- if not value.startswith('['):
- assert os.path.isabs(nt.path), nt.path
- # commented as on Linux we might get
- # '/foo/bar (deleted)'
- # assert os.path.exists(nt.path), nt.path
- elif fname in ('addr', 'perms'):
- self.assertTrue(value)
- else:
- self.assertIsInstance(value, (int, long))
- assert value >= 0, value
-
- def num_handles(self, ret):
- if WINDOWS:
- self.assertGreaterEqual(ret, 0)
- else:
- self.assertGreaterEqual(ret, 0)
-
- def nice(self, ret):
- if POSIX:
- assert -20 <= ret <= 20, ret
- else:
- priorities = [getattr(psutil, x) for x in dir(psutil)
- if x.endswith('_PRIORITY_CLASS')]
- self.assertIn(ret, priorities)
-
- def num_ctx_switches(self, ret):
- self.assertTrue(ret.voluntary >= 0)
- self.assertTrue(ret.involuntary >= 0)
-
- def rlimit(self, ret):
- self.assertEqual(len(ret), 2)
- self.assertGreaterEqual(ret[0], -1)
- self.assertGreaterEqual(ret[1], -1)
-
-
-# ===================================================================
-# --- Limited user tests
-# ===================================================================
-
-@unittest.skipUnless(POSIX, "UNIX only")
-@unittest.skipUnless(hasattr(os, 'getuid') and os.getuid() == 0,
- "super user privileges are required")
-class LimitedUserTestCase(TestProcess):
- """Repeat the previous tests by using a limited user.
- Executed only on UNIX and only if the user who run the test script
- is root.
- """
- # the uid/gid the test suite runs under
- if hasattr(os, 'getuid'):
- PROCESS_UID = os.getuid()
- PROCESS_GID = os.getgid()
-
- def __init__(self, *args, **kwargs):
- TestProcess.__init__(self, *args, **kwargs)
- # re-define all existent test methods in order to
- # ignore AccessDenied exceptions
- for attr in [x for x in dir(self) if x.startswith('test')]:
- meth = getattr(self, attr)
-
- def test_(self):
- try:
- meth()
- except psutil.AccessDenied:
- pass
- setattr(self, attr, types.MethodType(test_, self))
-
- def setUp(self):
- safe_remove(TESTFN)
- TestProcess.setUp(self)
- os.setegid(1000)
- os.seteuid(1000)
-
- def tearDown(self):
- os.setegid(self.PROCESS_UID)
- os.seteuid(self.PROCESS_GID)
- TestProcess.tearDown(self)
-
- def test_nice(self):
- try:
- psutil.Process().nice(-1)
- except psutil.AccessDenied:
- pass
- else:
- self.fail("exception not raised")
-
- def test_zombie_process(self):
- # causes problems if test test suite is run as root
- pass
-
-
-# ===================================================================
-# --- Misc tests
-# ===================================================================
-
-class TestMisc(unittest.TestCase):
- """Misc / generic tests."""
-
- def test_process__repr__(self, func=repr):
- p = psutil.Process()
- r = func(p)
- self.assertIn("psutil.Process", r)
- self.assertIn("pid=%s" % p.pid, r)
- self.assertIn("name=", r)
- self.assertIn(p.name(), r)
- with mock.patch.object(psutil.Process, "name",
- side_effect=psutil.ZombieProcess(os.getpid())):
- p = psutil.Process()
- r = func(p)
- self.assertIn("pid=%s" % p.pid, r)
- self.assertIn("zombie", r)
- self.assertNotIn("name=", r)
- with mock.patch.object(psutil.Process, "name",
- side_effect=psutil.NoSuchProcess(os.getpid())):
- p = psutil.Process()
- r = func(p)
- self.assertIn("pid=%s" % p.pid, r)
- self.assertIn("terminated", r)
- self.assertNotIn("name=", r)
-
- def test_process__str__(self):
- self.test_process__repr__(func=str)
-
- def test_no_such_process__repr__(self, func=repr):
- self.assertEqual(
- repr(psutil.NoSuchProcess(321)),
- "psutil.NoSuchProcess process no longer exists (pid=321)")
- self.assertEqual(
- repr(psutil.NoSuchProcess(321, name='foo')),
- "psutil.NoSuchProcess process no longer exists (pid=321, "
- "name='foo')")
- self.assertEqual(
- repr(psutil.NoSuchProcess(321, msg='foo')),
- "psutil.NoSuchProcess foo")
-
- def test_zombie_process__repr__(self, func=repr):
- self.assertEqual(
- repr(psutil.ZombieProcess(321)),
- "psutil.ZombieProcess process still exists but it's a zombie "
- "(pid=321)")
- self.assertEqual(
- repr(psutil.ZombieProcess(321, name='foo')),
- "psutil.ZombieProcess process still exists but it's a zombie "
- "(pid=321, name='foo')")
- self.assertEqual(
- repr(psutil.ZombieProcess(321, name='foo', ppid=1)),
- "psutil.ZombieProcess process still exists but it's a zombie "
- "(pid=321, name='foo', ppid=1)")
- self.assertEqual(
- repr(psutil.ZombieProcess(321, msg='foo')),
- "psutil.ZombieProcess foo")
-
- def test_access_denied__repr__(self, func=repr):
- self.assertEqual(
- repr(psutil.AccessDenied(321)),
- "psutil.AccessDenied (pid=321)")
- self.assertEqual(
- repr(psutil.AccessDenied(321, name='foo')),
- "psutil.AccessDenied (pid=321, name='foo')")
- self.assertEqual(
- repr(psutil.AccessDenied(321, msg='foo')),
- "psutil.AccessDenied foo")
-
- def test_timeout_expired__repr__(self, func=repr):
- self.assertEqual(
- repr(psutil.TimeoutExpired(321)),
- "psutil.TimeoutExpired timeout after 321 seconds")
- self.assertEqual(
- repr(psutil.TimeoutExpired(321, pid=111)),
- "psutil.TimeoutExpired timeout after 321 seconds (pid=111)")
- self.assertEqual(
- repr(psutil.TimeoutExpired(321, pid=111, name='foo')),
- "psutil.TimeoutExpired timeout after 321 seconds "
- "(pid=111, name='foo')")
-
- def test_process__eq__(self):
- p1 = psutil.Process()
- p2 = psutil.Process()
- self.assertEqual(p1, p2)
- p2._ident = (0, 0)
- self.assertNotEqual(p1, p2)
- self.assertNotEqual(p1, 'foo')
-
- def test_process__hash__(self):
- s = set([psutil.Process(), psutil.Process()])
- self.assertEqual(len(s), 1)
-
- def test__all__(self):
- dir_psutil = dir(psutil)
- for name in dir_psutil:
- if name in ('callable', 'error', 'namedtuple',
- 'long', 'test', 'NUM_CPUS', 'BOOT_TIME',
- 'TOTAL_PHYMEM'):
- continue
- if not name.startswith('_'):
- try:
- __import__(name)
- except ImportError:
- if name not in psutil.__all__:
- fun = getattr(psutil, name)
- if fun is None:
- continue
- if (fun.__doc__ is not None and
- 'deprecated' not in fun.__doc__.lower()):
- self.fail('%r not in psutil.__all__' % name)
-
- # Import 'star' will break if __all__ is inconsistent, see:
- # https://github.com/giampaolo/psutil/issues/656
- # Can't do `from psutil import *` as it won't work on python 3
- # so we simply iterate over __all__.
- for name in psutil.__all__:
- self.assertIn(name, dir_psutil)
-
- def test_version(self):
- self.assertEqual('.'.join([str(x) for x in psutil.version_info]),
- psutil.__version__)
-
- def test_memoize(self):
- from psutil._common import memoize
-
- @memoize
- def foo(*args, **kwargs):
- "foo docstring"
- calls.append(None)
- return (args, kwargs)
-
- calls = []
- # no args
- for x in range(2):
- ret = foo()
- expected = ((), {})
- self.assertEqual(ret, expected)
- self.assertEqual(len(calls), 1)
- # with args
- for x in range(2):
- ret = foo(1)
- expected = ((1, ), {})
- self.assertEqual(ret, expected)
- self.assertEqual(len(calls), 2)
- # with args + kwargs
- for x in range(2):
- ret = foo(1, bar=2)
- expected = ((1, ), {'bar': 2})
- self.assertEqual(ret, expected)
- self.assertEqual(len(calls), 3)
- # clear cache
- foo.cache_clear()
- ret = foo()
- expected = ((), {})
- self.assertEqual(ret, expected)
- self.assertEqual(len(calls), 4)
- # docstring
- self.assertEqual(foo.__doc__, "foo docstring")
-
- def test_isfile_strict(self):
- from psutil._common import isfile_strict
- this_file = os.path.abspath(__file__)
- assert isfile_strict(this_file)
- assert not isfile_strict(os.path.dirname(this_file))
- with mock.patch('psutil._common.os.stat',
- side_effect=OSError(errno.EPERM, "foo")):
- self.assertRaises(OSError, isfile_strict, this_file)
- with mock.patch('psutil._common.os.stat',
- side_effect=OSError(errno.EACCES, "foo")):
- self.assertRaises(OSError, isfile_strict, this_file)
- with mock.patch('psutil._common.os.stat',
- side_effect=OSError(errno.EINVAL, "foo")):
- assert not isfile_strict(this_file)
- with mock.patch('psutil._common.stat.S_ISREG', return_value=False):
- assert not isfile_strict(this_file)
-
- def test_serialization(self):
- def check(ret):
- if json is not None:
- json.loads(json.dumps(ret))
- a = pickle.dumps(ret)
- b = pickle.loads(a)
- self.assertEqual(ret, b)
-
- check(psutil.Process().as_dict())
- check(psutil.virtual_memory())
- check(psutil.swap_memory())
- check(psutil.cpu_times())
- check(psutil.cpu_times_percent(interval=0))
- check(psutil.net_io_counters())
- if LINUX and not os.path.exists('/proc/diskstats'):
- pass
- else:
- if not APPVEYOR:
- check(psutil.disk_io_counters())
- check(psutil.disk_partitions())
- check(psutil.disk_usage(os.getcwd()))
- check(psutil.users())
-
- def test_setup_script(self):
- here = os.path.abspath(os.path.dirname(__file__))
- setup_py = os.path.realpath(os.path.join(here, '..', 'setup.py'))
- module = imp.load_source('setup', setup_py)
- self.assertRaises(SystemExit, module.setup)
- self.assertEqual(module.get_version(), psutil.__version__)
-
- def test_ad_on_process_creation(self):
- # We are supposed to be able to instantiate Process also in case
- # of zombie processes or access denied.
- with mock.patch.object(psutil.Process, 'create_time',
- side_effect=psutil.AccessDenied) as meth:
- psutil.Process()
- assert meth.called
- with mock.patch.object(psutil.Process, 'create_time',
- side_effect=psutil.ZombieProcess(1)) as meth:
- psutil.Process()
- assert meth.called
- with mock.patch.object(psutil.Process, 'create_time',
- side_effect=ValueError) as meth:
- with self.assertRaises(ValueError):
- psutil.Process()
- assert meth.called
-
-
-# ===================================================================
-# --- Example script tests
-# ===================================================================
-
-class TestExampleScripts(unittest.TestCase):
- """Tests for scripts in the examples directory."""
-
- def assert_stdout(self, exe, args=None):
- exe = os.path.join(EXAMPLES_DIR, exe)
- if args:
- exe = exe + ' ' + args
- try:
- out = sh(sys.executable + ' ' + exe).strip()
- except RuntimeError as err:
- if 'AccessDenied' in str(err):
- return str(err)
- else:
- raise
- assert out, out
- return out
-
- def assert_syntax(self, exe, args=None):
- exe = os.path.join(EXAMPLES_DIR, exe)
- with open(exe, 'r') as f:
- src = f.read()
- ast.parse(src)
-
- def test_check_presence(self):
- # make sure all example scripts have a test method defined
- meths = dir(self)
- for name in os.listdir(EXAMPLES_DIR):
- if name.endswith('.py'):
- if 'test_' + os.path.splitext(name)[0] not in meths:
- # self.assert_stdout(name)
- self.fail('no test defined for %r script'
- % os.path.join(EXAMPLES_DIR, name))
-
- def test_disk_usage(self):
- self.assert_stdout('disk_usage.py')
-
- def test_free(self):
- self.assert_stdout('free.py')
-
- def test_meminfo(self):
- self.assert_stdout('meminfo.py')
-
- def test_process_detail(self):
- self.assert_stdout('process_detail.py')
-
- @unittest.skipIf(APPVEYOR, "can't find users on Appveyor")
- def test_who(self):
- self.assert_stdout('who.py')
-
- def test_ps(self):
- self.assert_stdout('ps.py')
-
- def test_pstree(self):
- self.assert_stdout('pstree.py')
-
- def test_netstat(self):
- self.assert_stdout('netstat.py')
-
- @unittest.skipIf(TRAVIS, "permission denied on travis")
- def test_ifconfig(self):
- self.assert_stdout('ifconfig.py')
-
- def test_pmap(self):
- self.assert_stdout('pmap.py', args=str(os.getpid()))
-
- @unittest.skipIf(ast is None,
- 'ast module not available on this python version')
- def test_killall(self):
- self.assert_syntax('killall.py')
-
- @unittest.skipIf(ast is None,
- 'ast module not available on this python version')
- def test_nettop(self):
- self.assert_syntax('nettop.py')
-
- @unittest.skipIf(ast is None,
- 'ast module not available on this python version')
- def test_top(self):
- self.assert_syntax('top.py')
-
- @unittest.skipIf(ast is None,
- 'ast module not available on this python version')
- def test_iotop(self):
- self.assert_syntax('iotop.py')
-
- def test_pidof(self):
- output = self.assert_stdout('pidof.py %s' % psutil.Process().name())
- self.assertIn(str(os.getpid()), output)
-
-
-def main():
- tests = []
- test_suite = unittest.TestSuite()
- tests.append(TestSystemAPIs)
- tests.append(TestProcess)
- tests.append(TestFetchAllProcesses)
- tests.append(TestMisc)
- tests.append(TestExampleScripts)
- tests.append(LimitedUserTestCase)
-
- if POSIX:
- from _posix import PosixSpecificTestCase
- tests.append(PosixSpecificTestCase)
-
- # import the specific platform test suite
- stc = None
- if LINUX:
- from _linux import LinuxSpecificTestCase as stc
- elif WINDOWS:
- from _windows import WindowsSpecificTestCase as stc
- from _windows import TestDualProcessImplementation
- tests.append(TestDualProcessImplementation)
- elif OSX:
- from _osx import OSXSpecificTestCase as stc
- elif BSD:
- from _bsd import BSDSpecificTestCase as stc
- elif SUNOS:
- from _sunos import SunOSSpecificTestCase as stc
- if stc is not None:
- tests.append(stc)
-
- for test_class in tests:
- test_suite.addTest(unittest.makeSuite(test_class))
- result = unittest.TextTestRunner(verbosity=2).run(test_suite)
- return result.wasSuccessful()
-
-if __name__ == '__main__':
- if not main():
- sys.exit(1)
diff --git a/python/psutil/tox.ini b/python/psutil/tox.ini
deleted file mode 100644
index d80dd174b..000000000
--- a/python/psutil/tox.ini
+++ /dev/null
@@ -1,32 +0,0 @@
-# Tox (http://tox.testrun.org/) is a tool for running tests
-# in multiple virtualenvs. This configuration file will run the
-# test suite on all supported python versions.
-# To use it run "pip install tox" and then run "tox" from this
-# directory.
-
-[tox]
-envlist = py26, py27, py32, py33, py34
-
-[testenv]
-deps =
- flake8
- pytest
- py26: ipaddress
- py26: mock==1.0.1
- py26: unittest2
- py27: ipaddress
- py27: mock
- py32: ipaddress
- py32: mock
- py33: ipaddress
-
-setenv =
- PYTHONPATH = {toxinidir}/test
-
-commands =
- py.test {posargs}
- git ls-files | grep \\.py$ | xargs flake8
-
-# suppress "WARNING: 'git' command found but not installed in testenv
-whitelist_externals = git
-usedevelop = True