summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2015-01-03 11:33:30 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2015-01-03 11:33:30 +0100
commitbba6b31848c6ca1a9023049d4c544293f4b5c889 (patch)
tree4ec76e0511118930ee655ffc15f18445ee36d90f
parent80b04a57c00036926de9f872ee858b8497a43440 (diff)
parent39af7af7ca5438d7feac816b457b9ebe48747ddd (diff)
downloadpsutil-bba6b31848c6ca1a9023049d4c544293f4b5c889.tar.gz
merge from master
-rw-r--r--CREDITS7
-rw-r--r--HISTORY.rst10
-rw-r--r--README.rst16
-rw-r--r--TODO16
-rw-r--r--docs/index.rst19
-rwxr-xr-xexamples/iotop.py13
-rwxr-xr-xexamples/nettop.py10
-rwxr-xr-xexamples/top.py11
-rw-r--r--psutil/__init__.py74
-rw-r--r--psutil/_common.py30
-rw-r--r--psutil/_compat.py4
-rw-r--r--psutil/_psbsd.py33
-rwxr-xr-x[-rw-r--r--]psutil/_pslinux.py10
-rw-r--r--psutil/_psosx.py5
-rw-r--r--psutil/_psposix.py6
-rw-r--r--psutil/_pssunos.py11
-rw-r--r--psutil/_psutil_bsd.c41
-rw-r--r--psutil/_psutil_windows.c11
-rw-r--r--psutil/_pswindows.py13
-rw-r--r--psutil/arch/windows/ntextapi.h5
-rw-r--r--psutil/arch/windows/process_handles.c128
-rw-r--r--psutil/arch/windows/process_info.h9
-rw-r--r--setup.py1
-rw-r--r--test/_bsd.py1
-rw-r--r--test/_windows.py10
-rw-r--r--test/test_memory_leaks.py10
-rw-r--r--test/test_psutil.py36
-rw-r--r--tox.ini1
28 files changed, 347 insertions, 194 deletions
diff --git a/CREDITS b/CREDITS
index fac83f68..a4b1b9ef 100644
--- a/CREDITS
+++ b/CREDITS
@@ -282,4 +282,9 @@ E: bruno.binet@gmail.com
I: 572
N: Gabi Davar
-I: 581
+I: 578, 581
+
+N: spacewanderlzx
+C: Guangzhou,China
+E: spacewanderlzx@gmail.com
+I: 555 \ No newline at end of file
diff --git a/HISTORY.rst b/HISTORY.rst
index 4632cca5..af3c7c0b 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -6,7 +6,17 @@ Bug tracker at https://github.com/giampaolo/psutil/issues
**Enhancements**
- #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.
+**Bug fixes**
+
+- #555: [Linux] psutil.users() correctly handles ":0" as an alias for
+ "localhost"
+- #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.
2.2.1 - 2015-02-02
==================
diff --git a/README.rst b/README.rst
index e0e1c367..12843b8d 100644
--- a/README.rst
+++ b/README.rst
@@ -142,10 +142,10 @@ Network
'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=2, type=1, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
- pconn(fd=117, family=2, type=1, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
- pconn(fd=-1, family=2, type=1, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
- pconn(fd=-1, family=2, type=1, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
+ [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)
...]
Other system info
@@ -229,10 +229,10 @@ Process management
[popenfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)]
>>>
>>> p.connections()
- [pconn(fd=115, family=2, type=1, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
- pconn(fd=117, family=2, type=1, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
- pconn(fd=119, family=2, type=1, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
- pconn(fd=123, family=2, type=1, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
+ [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
diff --git a/TODO b/TODO
index 9e0292e9..80355392 100644
--- a/TODO
+++ b/TODO
@@ -21,7 +21,8 @@ HIGHER PRIORITY
* #269: expose network ifaces RX/TW queues.
- * Process.threads(): thread names
+ * 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)
@@ -50,10 +51,7 @@ LOWER PRIORITY
* #357: what CPU a process is on.
- * thread names:
- * https://code.google.com/p/plcrashreporter/issues/detail?id=65
-
- * Doc / wiki which compares similarities between UNIX cli tools and psutil.
+ * 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()
@@ -65,7 +63,13 @@ LOWER PRIORITY
DEBATABLE
=========
- * support wheels? http://pythonwheels.com/
+ * 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).
diff --git a/docs/index.rst b/docs/index.rst
index 76de5936..92d7fe73 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -391,10 +391,10 @@ Network
>>> import psutil
>>> psutil.net_connections()
- [pconn(fd=115, family=2, type=1, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
- pconn(fd=117, family=2, type=1, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
- pconn(fd=-1, family=2, type=1, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
- pconn(fd=-1, family=2, type=1, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
+ [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
@@ -878,7 +878,8 @@ Process class
`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()))``.
+ ``list(range(psutil.cpu_count()))``. On set raises ``ValueError`` in case
+ an invalid CPU number is specified.
>>> import psutil
>>> psutil.cpu_count()
@@ -1082,10 +1083,10 @@ Process class
>>> p.name()
'firefox'
>>> p.connections()
- [pconn(fd=115, family=2, type=1, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
- pconn(fd=117, family=2, type=1, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
- pconn(fd=119, family=2, type=1, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
- pconn(fd=123, family=2, type=1, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
+ [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()
diff --git a/examples/iotop.py b/examples/iotop.py
index a0986782..be3819b8 100755
--- a/examples/iotop.py
+++ b/examples/iotop.py
@@ -30,14 +30,15 @@ PID USER DISK READ DISK WRITE COMMAND
Author: Giampaolo Rodola' <g.rodola@gmail.com>
"""
-import os
+import atexit
+import time
import sys
-import psutil
-if not hasattr(psutil.Process, 'io_counters') or os.name != 'posix':
+try:
+ import curses
+except ImportError:
sys.exit('platform not supported')
-import time
-import curses
-import atexit
+
+import psutil
# --- curses stuff
diff --git a/examples/nettop.py b/examples/nettop.py
index 857285cf..7a8343ee 100755
--- a/examples/nettop.py
+++ b/examples/nettop.py
@@ -31,13 +31,13 @@ pkts-sent 0 0
pkts-recv 1214470 0
"""
-import sys
-import os
-if os.name != 'posix':
- sys.exit('platform not supported')
import atexit
-import curses
import time
+import sys
+try:
+ import curses
+except ImportError:
+ sys.exit('platform not supported')
import psutil
diff --git a/examples/top.py b/examples/top.py
index a305297f..7aebef1d 100755
--- a/examples/top.py
+++ b/examples/top.py
@@ -34,14 +34,15 @@ PID USER NI VIRT RES CPU% MEM% TIME+ NAME
...
"""
+from datetime import datetime, timedelta
+import atexit
import os
+import time
import sys
-if os.name != 'posix':
+try:
+ import curses
+except ImportError:
sys.exit('platform not supported')
-import atexit
-import curses
-import time
-from datetime import datetime, timedelta
import psutil
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 4e50563a..10239dc9 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -12,33 +12,6 @@ in Python.
from __future__ import division
-__author__ = "Giampaolo Rodola'"
-__version__ = "3.0.0"
-version_info = tuple([int(num) for num in __version__.split('.')])
-
-__all__ = [
- # exceptions
- "Error", "NoSuchProcess", "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",
- # 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
- "disk_io_counters", "disk_partitions", "disk_usage", # disk
- "users", "boot_time", # others
-]
-
import collections
import errno
import functools
@@ -73,7 +46,7 @@ from psutil._common import (STATUS_RUNNING, # NOQA
STATUS_LOCKED,
STATUS_IDLE, # bsd
STATUS_WAITING, # bsd
- STATUS_LOCKED) # bsd
+)
from psutil._common import (CONN_ESTABLISHED,
CONN_SYN_SENT,
@@ -89,7 +62,7 @@ from psutil._common import (CONN_ESTABLISHED,
CONN_NONE)
if sys.platform.startswith("linux"):
- import psutil._pslinux as _psplatform
+ from psutil import _pslinux as _psplatform
from psutil._pslinux import (phymem_buffers, # NOQA
cached_phymem)
@@ -138,7 +111,7 @@ if sys.platform.startswith("linux"):
del _psutil_linux
elif sys.platform.startswith("win32"):
- import psutil._pswindows as _psplatform
+ from psutil import _pswindows as _psplatform
from _psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS, # NOQA
BELOW_NORMAL_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS,
@@ -148,23 +121,46 @@ elif sys.platform.startswith("win32"):
from psutil._pswindows import CONN_DELETE_TCB # NOQA
elif sys.platform.startswith("darwin"):
- import psutil._psosx as _psplatform
+ from psutil import _psosx as _psplatform
elif sys.platform.startswith("freebsd"):
- import psutil._psbsd as _psplatform
+ from psutil import _psbsd as _psplatform
elif sys.platform.startswith("sunos"):
- import psutil._pssunos as _psplatform
+ from psutil import _pssunos as _psplatform
from psutil._pssunos import (CONN_IDLE, # NOQA
CONN_BOUND)
else:
raise NotImplementedError('platform %s is not supported' % sys.platform)
-# extend the local __all__ context
-__all__.extend(_psplatform.__extra__all__)
-
+__all__ = [
+ # exceptions
+ "Error", "NoSuchProcess", "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",
+ # 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
+ "disk_io_counters", "disk_partitions", "disk_usage", # disk
+ "users", "boot_time", # others
+]
+__all__.extend(_psplatform.__extra__all__)
+__author__ = "Giampaolo Rodola'"
+__version__ = "3.0.0"
+version_info = tuple([int(num) for num in __version__.split('.')])
AF_LINK = _psplatform.AF_LINK
_TOTAL_PHYMEM = None
_POSIX = os.name == 'posix'
@@ -855,9 +851,11 @@ class Process(object):
blocking = interval is not None and interval > 0.0
num_cpus = cpu_count()
if _POSIX:
- timer = lambda: _timer() * num_cpus
+ def timer():
+ return _timer() * num_cpus
else:
- timer = lambda: sum(cpu_times())
+ def timer():
+ return sum(cpu_times())
if blocking:
st1 = timer()
pt1 = self._proc.cpu_times()
diff --git a/psutil/_common.py b/psutil/_common.py
index d52cea87..cc223cf8 100644
--- a/psutil/_common.py
+++ b/psutil/_common.py
@@ -17,6 +17,10 @@ try:
import threading
except ImportError:
import dummy_threading as threading
+try:
+ import enum # py >= 3.4
+except ImportError:
+ enum = None
from collections import namedtuple
from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
@@ -160,6 +164,30 @@ def isfile_strict(path):
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 = {
@@ -184,7 +212,7 @@ if AF_UNIX is not None:
"unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
})
-del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM, socket
+del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM
# --- namedtuples for psutil.* system-related functions
diff --git a/psutil/_compat.py b/psutil/_compat.py
index b52a04f0..dbb8dc1c 100644
--- a/psutil/_compat.py
+++ b/psutil/_compat.py
@@ -6,12 +6,12 @@
"""Module which provides compatibility with older Python versions."""
-__all__ = ["PY3", "long", "xrange", "unicode", "callable", "lru_cache"]
-
import collections
import functools
import sys
+__all__ = ["PY3", "long", "xrange", "unicode", "callable", "lru_cache"]
+
PY3 = sys.version_info[0] == 3
if PY3:
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index d59c23f2..eb09f9dc 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -15,7 +15,8 @@ from collections import namedtuple
from psutil import _common
from psutil import _psposix
-from psutil._common import conn_tmap, usage_percent
+from psutil._common import conn_tmap, usage_percent, sockfam_to_enum
+from psutil._common import socktype_to_enum
import _psutil_bsd as cext
import _psutil_posix
@@ -50,7 +51,7 @@ TCP_STATUSES = {
}
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-AF_LINK = socket.AF_LINK
+AF_LINK = _psutil_posix.AF_LINK
# extend base mem ntuple with BSD-specific memory metrics
svmem = namedtuple(
@@ -186,16 +187,25 @@ def net_connections(kind):
raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in conn_tmap])))
families, types = conn_tmap[kind]
- ret = []
+ 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:
- status = TCP_STATUSES[status]
+ 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.append(nt)
- return ret
+ ret.add(nt)
+ return list(ret)
pids = cext.pids
@@ -315,6 +325,8 @@ class Process(object):
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)
@@ -397,6 +409,14 @@ class Process(object):
@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:
@@ -405,7 +425,6 @@ class Process(object):
# on because the set does not overlap with the thread's
# anonymous mask>>
if err.errno in (errno.EINVAL, errno.EDEADLK):
- allcpus = tuple(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in allcpus:
raise ValueError("invalid CPU #%i (choose between %s)"
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index fae23734..e1f9560e 100644..100755
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -21,7 +21,7 @@ from collections import namedtuple, defaultdict
from psutil import _common
from psutil import _psposix
-from psutil._common import (isfile_strict, usage_percent, deprecated)
+from psutil._common import isfile_strict, usage_percent, deprecated
from psutil._compat import PY3
import _psutil_linux as cext
import _psutil_posix
@@ -291,7 +291,7 @@ def users():
# to use them in the future.
if not user_process:
continue
- if hostname == ':0.0':
+ if hostname == ':0.0' or hostname == ':0':
hostname = 'localhost'
nt = _common.suser(user, tty or None, hostname, tstamp)
retlist.append(nt)
@@ -504,7 +504,7 @@ class Connections:
return []
else:
inodes = self.get_all_inodes()
- ret = []
+ ret = set()
for f, family, type_ in self.tmap[kind]:
if family in (socket.AF_INET, socket.AF_INET6):
ls = self.process_inet(
@@ -519,8 +519,8 @@ class Connections:
else:
conn = _common.sconn(fd, family, type_, laddr, raddr,
status, bound_pid)
- ret.append(conn)
- return ret
+ ret.add(conn)
+ return list(ret)
_connections = Connections()
diff --git a/psutil/_psosx.py b/psutil/_psosx.py
index 2965b2c2..8d382e57 100644
--- a/psutil/_psosx.py
+++ b/psutil/_psosx.py
@@ -15,6 +15,7 @@ from collections import namedtuple
from psutil import _common
from psutil import _psposix
from psutil._common import conn_tmap, usage_percent, isfile_strict
+from psutil._common import sockfam_to_enum, socktype_to_enum
import _psutil_osx as cext
import _psutil_posix
@@ -24,7 +25,7 @@ __extra__all__ = []
# --- constants
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-AF_LINK = socket.AF_LINK
+AF_LINK = _psutil_posix.AF_LINK
# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
TCP_STATUSES = {
@@ -295,6 +296,8 @@ class Process(object):
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
diff --git a/psutil/_psposix.py b/psutil/_psposix.py
index 94db351e..1f7dc96e 100644
--- a/psutil/_psposix.py
+++ b/psutil/_psposix.py
@@ -68,10 +68,12 @@ def wait_pid(pid, timeout=None):
timer = getattr(time, 'monotonic', time.time)
if timeout is not None:
- waitcall = lambda: os.waitpid(pid, os.WNOHANG)
+ def waitcall():
+ return os.waitpid(pid, os.WNOHANG)
stop_at = timer() + timeout
else:
- waitcall = lambda: os.waitpid(pid, 0)
+ def waitcall():
+ return os.waitpid(pid, 0)
delay = 0.0001
while True:
diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py
index 17968f67..031231b8 100644
--- a/psutil/_pssunos.py
+++ b/psutil/_pssunos.py
@@ -15,7 +15,8 @@ from collections import namedtuple
from psutil import _common
from psutil import _psposix
-from psutil._common import usage_percent, isfile_strict
+from psutil._common import isfile_strict, socktype_to_enum, sockfam_to_enum
+from psutil._common import usage_percent
from psutil._compat import PY3
import _psutil_posix
import _psutil_sunos as cext
@@ -212,7 +213,7 @@ def net_connections(kind, _pid=-1):
% (kind, ', '.join([repr(x) for x in cmap])))
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid, families, types)
- ret = []
+ ret = set()
for item in rawlist:
fd, fam, type_, laddr, raddr, status, pid = item
if fam not in families:
@@ -220,12 +221,14 @@ def net_connections(kind, _pid=-1):
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.append(nt)
- return ret
+ ret.add(nt)
+ return list(ret)
def wrap_exceptions(fun):
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index 0128c8c8..615c04ba 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -95,7 +95,7 @@ psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
/*
* Set exception to AccessDenied if pid exists else NoSuchProcess.
*/
-int
+void
psutil_raise_ad_or_nsp(long pid) {
if (psutil_pid_exists(pid) == 0) {
NoSuchProcess();
@@ -905,7 +905,6 @@ psutil_fetch_tcplist(void)
{
char *buf;
size_t len;
- int error;
for (;;) {
if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) < 0) {
@@ -1158,7 +1157,7 @@ psutil_proc_connections(PyObject *self, PyObject *args)
sun = (struct sockaddr_un *)&kif->kf_sa_local;
snprintf(
path, sizeof(path), "%.*s",
- (sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
+ (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
sun->sun_path);
tuple = Py_BuildValue("(iiisOi)",
@@ -1799,11 +1798,12 @@ int psutil_gather_inet(int proto, PyObject *py_retlist)
struct xtcpcb *xtp;
struct inpcb *inp;
struct xsocket *so;
- struct sock *sock;
- const char *varname;
+ const char *varname = NULL;
size_t len, bufsize;
void *buf;
- int hash, retry, vflag, type;
+ int hash;
+ int retry;
+ int type = NULL;
PyObject *tuple = NULL;
PyObject *laddr = NULL;
@@ -1875,7 +1875,8 @@ int psutil_gather_inet(int proto, PyObject *py_retlist)
inp = &xtp->xt_inp;
so = &xtp->xt_socket;
char lip[200], rip[200];
- int family, lport, rport, pid, status;
+ int family = NULL;
+ int lport, rport, pid, status;
hash = (int)((uintptr_t)so->xso_so % HASHSIZE);
pid = psutil_get_pid_from_sock(hash);
@@ -1933,12 +1934,14 @@ int psutil_gather_unix(int proto, PyObject *py_retlist)
{
struct xunpgen *xug, *exug;
struct xunpcb *xup;
- struct sock *sock;
- const char *varname, *protoname;
- size_t len, bufsize;
+ const char *varname = NULL;
+ const char *protoname = NULL;
+ size_t len;
+ size_t bufsize;
void *buf;
- int hash, retry;
- int family, lport, rport, pid;
+ int hash;
+ int retry;
+ int pid;
struct sockaddr_un *sun;
char path[PATH_MAX];
@@ -2002,7 +2005,7 @@ int psutil_gather_unix(int proto, PyObject *py_retlist)
sun = (struct sockaddr_un *)&xup->xu_addr;
snprintf(path, sizeof(path), "%.*s",
- (sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
+ (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
sun->sun_path);
tuple = Py_BuildValue("(iiisOii)", -1, AF_UNIX, proto, path, Py_None,
@@ -2033,8 +2036,6 @@ error:
static PyObject*
psutil_net_connections(PyObject* self, PyObject* args)
{
- PyObject *af_filter = NULL;
- PyObject *type_filter = NULL;
PyObject *py_retlist = PyList_New(0);
if (psutil_populate_xfiles() != 1)
@@ -2122,14 +2123,12 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
PyObject *py_cpu_set;
PyObject *py_cpu_seq = NULL;
- if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set)) {
- goto error;
- }
+ 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) {
- goto error;
- }
+ if (!py_cpu_seq)
+ return NULL;
seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);
// calculate the mask
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 13f5717e..0427bc1d 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -568,7 +568,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
if (NULL == hProcess) {
return NULL;
}
- if (GetProcessImageFileNameW(hProcess, &exe, MAX_PATH) == 0) {
+ if (GetProcessImageFileNameW(hProcess, exe, MAX_PATH) == 0) {
CloseHandle(hProcess);
PyErr_SetFromWindowsErr(0);
return NULL;
@@ -602,7 +602,9 @@ psutil_proc_memory_info(PyObject *self, PyObject *args)
return NULL;
}
- if (! GetProcessMemoryInfo(hProcess, &cnt, sizeof(cnt)) ) {
+ if (! GetProcessMemoryInfo(hProcess, (PPROCESS_MEMORY_COUNTERS)&cnt,
+ sizeof(cnt)) )
+ {
CloseHandle(hProcess);
return PyErr_SetFromWindowsErr(0);
}
@@ -2125,8 +2127,8 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
{
DWORD pid;
HANDLE hProcess;
- PDWORD_PTR proc_mask;
- PDWORD_PTR system_mask;
+ DWORD_PTR proc_mask;
+ DWORD_PTR system_mask;
if (! PyArg_ParseTuple(args, "l", &pid)) {
return NULL;
@@ -2261,7 +2263,6 @@ static PyObject *
psutil_net_io_counters(PyObject *self, PyObject *args)
{
int attempts = 0;
- int i;
int outBufLen = 15000;
char ifname[MAX_PATH];
DWORD dwRetVal = 0;
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py
index ca495955..c9a68a0a 100644
--- a/psutil/_pswindows.py
+++ b/psutil/_pswindows.py
@@ -13,9 +13,11 @@ from collections import namedtuple
from psutil import _common
from psutil._common import conn_tmap, usage_percent, isfile_strict
+from psutil._common import sockfam_to_enum, socktype_to_enum
from psutil._compat import PY3, xrange, lru_cache
import _psutil_windows as cext
+
# 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",
@@ -168,16 +170,18 @@ def net_connections(kind, _pid=-1):
% (kind, ', '.join([repr(x) for x in conn_tmap])))
families, types = conn_tmap[kind]
rawlist = cext.net_connections(_pid, families, types)
- ret = []
+ 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.append(nt)
- return ret
+ ret.add(nt)
+ return list(ret)
def users():
@@ -446,7 +450,8 @@ class Process(object):
@wrap_exceptions
def cpu_affinity_get(self):
- from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
+ 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)
diff --git a/psutil/arch/windows/ntextapi.h b/psutil/arch/windows/ntextapi.h
index 298c0780..d1aa62df 100644
--- a/psutil/arch/windows/ntextapi.h
+++ b/psutil/arch/windows/ntextapi.h
@@ -4,6 +4,9 @@
* found in the LICENSE file.
*/
+#if !defined(__NTEXTAPI_H__)
+#define __NTEXTAPI_H__
+
typedef enum _KTHREAD_STATE {
Initialized,
Ready,
@@ -285,3 +288,5 @@ typedef enum _PROCESSINFOCLASS {
ProcessImageInformation,
MaxProcessInfoClass
} PROCESSINFOCLASS;
+
+#endif // __NTEXTAPI_H__
diff --git a/psutil/arch/windows/process_handles.c b/psutil/arch/windows/process_handles.c
index f7479e99..6b0a4194 100644
--- a/psutil/arch/windows/process_handles.c
+++ b/psutil/arch/windows/process_handles.c
@@ -10,28 +10,26 @@
#endif
#include <Python.h>
-#include <windows.h>
#include <stdio.h>
+#include <windows.h>
+#include <strsafe.h>
#include "process_handles.h"
#ifndef NT_SUCCESS
#define NT_SUCCESS(x) ((x) >= 0)
#endif
+
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
-#define SystemHandleInformation 16
+#include <winternl.h>
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2
+#define HANDLE_TYPE_FILE 28
-typedef LONG NTSTATUS;
-typedef struct _UNICODE_STRING {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-} UNICODE_STRING, *PUNICODE_STRING;
+typedef LONG NTSTATUS;
typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
ULONG SystemInformationClass,
@@ -58,19 +56,29 @@ typedef NTSTATUS (NTAPI *_NtQueryObject)(
PULONG ReturnLength
);
-typedef struct _SYSTEM_HANDLE {
- ULONG ProcessId;
- BYTE ObjectTypeNumber;
- BYTE Flags;
- USHORT Handle;
+
+// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
+const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64;
+
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
+{
PVOID Object;
- ACCESS_MASK GrantedAccess;
-} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
+ 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 struct _SYSTEM_HANDLE_INFORMATION {
- ULONG HandleCount;
- SYSTEM_HANDLE Handles[1];
-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _POOL_TYPE {
NonPagedPool,
@@ -114,28 +122,62 @@ GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
}
+void PrintError(LPTSTR lpszFunction)
+{
+ // Retrieve the system error message for the last-error code
+
+ LPVOID lpMsgBuf;
+ LPVOID lpDisplayBuf;
+ DWORD dw = GetLastError();
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL );
+
+ // Display the error message
+ lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
+ (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
+ StringCchPrintf((LPTSTR)lpDisplayBuf,
+ LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+ TEXT("%s failed with error %d: %s"),
+ lpszFunction, dw, lpMsgBuf);
+
+ wprintf(lpDisplayBuf);
+ LocalFree(lpMsgBuf);
+ LocalFree(GetLastError);
+}
PyObject *
psutil_get_open_files(long pid, HANDLE processHandle)
{
_NtQuerySystemInformation NtQuerySystemInformation =
GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
+
_NtQueryObject NtQueryObject =
GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
NTSTATUS status;
- PSYSTEM_HANDLE_INFORMATION handleInfo;
+ PSYSTEM_HANDLE_INFORMATION_EX handleInfo;
ULONG handleInfoSize = 0x10000;
ULONG i;
ULONG fileNameLength;
PyObject *filesList = Py_BuildValue("[]");
PyObject *arg = NULL;
PyObject *fileFromWchar = NULL;
+ DWORD nReturn = 0;
if (filesList == NULL)
return NULL;
- handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
+ handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(GetProcessHeap(), 0,
+ handleInfoSize);
+
if (handleInfo == NULL) {
Py_DECREF(filesList);
PyErr_NoMemory();
@@ -145,25 +187,27 @@ psutil_get_open_files(long pid, HANDLE processHandle)
// NtQuerySystemInformation won't give us the correct buffer size,
// so we guess by doubling the buffer size.
while ((status = NtQuerySystemInformation(
- SystemHandleInformation,
+ SystemExtendedHandleInformation,
handleInfo,
handleInfoSize,
- NULL
+ &nReturn
)) == STATUS_INFO_LENGTH_MISMATCH)
{
- handleInfo = (PSYSTEM_HANDLE_INFORMATION) \
- realloc(handleInfo, handleInfoSize *= 2);
+ handleInfoSize *=2;
+ HeapFree(GetProcessHeap(), 0, handleInfo);
+ handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(
+ GetProcessHeap(), 0, handleInfoSize);
}
// NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH
if (!NT_SUCCESS(status)) {
Py_DECREF(filesList);
- free(handleInfo);
+ HeapFree(GetProcessHeap(), 0, handleInfo);
return NULL;
}
- for (i = 0; i < handleInfo->HandleCount; i++) {
- SYSTEM_HANDLE handle = handleInfo->Handles[i];
+ for (i = 0; i < handleInfo->NumberOfHandles; i++) {
+ PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = &handleInfo->Handles[i];
HANDLE dupHandle = NULL;
HANDLE mapHandle = NULL;
POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
@@ -175,31 +219,33 @@ psutil_get_open_files(long pid, HANDLE processHandle)
arg = NULL;
// Check if this handle belongs to the PID the user specified.
- if (handle.ProcessId != pid)
+ if (handle->UniqueProcessId != (HANDLE)pid ||
+ handle->ObjectTypeIndex != HANDLE_TYPE_FILE)
+ {
continue;
+ }
// Skip handles with the following access codes as the next call
// to NtDuplicateObject() or NtQueryObject() might hang forever.
- if ((handle.GrantedAccess == 0x0012019f)
- || (handle.GrantedAccess == 0x001a019f)
- || (handle.GrantedAccess == 0x00120189)
- || (handle.GrantedAccess == 0x00100000)) {
+ if ((handle->GrantedAccess == 0x0012019f)
+ || (handle->GrantedAccess == 0x001a019f)
+ || (handle->GrantedAccess == 0x00120189)
+ || (handle->GrantedAccess == 0x00100000)) {
continue;
}
- if (!DuplicateHandle(processHandle,
- handle.Handle,
+ if (!DuplicateHandle(processHandle,
+ handle->HandleValue,
GetCurrentProcess(),
&dupHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS))
{
- //printf("[%#x] Error: %d \n", handle.Handle, GetLastError());
+ //printf("[%#x] Error: %d \n", handle->HandleValue, GetLastError());
continue;
}
-
mapHandle = CreateFileMapping(dupHandle,
NULL,
PAGE_READONLY,
@@ -254,7 +300,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: (could not get name)\n",
- handle.Handle,
+ handle->HandleValue,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
@@ -300,7 +346,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: %.*S\n",
- handle.Handle,
+ handle->Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer,
objectName.Length / 2,
@@ -314,7 +360,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: (unnamed)\n",
- handle.Handle,
+ handle->Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
@@ -325,7 +371,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
free(objectNameInfo);
CloseHandle(dupHandle);
}
- free(handleInfo);
+ HeapFree(GetProcessHeap(), 0, handleInfo);
CloseHandle(processHandle);
return filesList;
diff --git a/psutil/arch/windows/process_info.h b/psutil/arch/windows/process_info.h
index 9544f5d6..a44c4ace 100644
--- a/psutil/arch/windows/process_info.h
+++ b/psutil/arch/windows/process_info.h
@@ -4,8 +4,13 @@
* 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);
@@ -15,3 +20,7 @@ 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/setup.py b/setup.py
index 17b57cfd..b027a64d 100644
--- a/setup.py
+++ b/setup.py
@@ -72,6 +72,7 @@ if sys.platform.startswith("win32"):
# 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),
],
diff --git a/test/_bsd.py b/test/_bsd.py
index 59be49bf..77691eb4 100644
--- a/test/_bsd.py
+++ b/test/_bsd.py
@@ -106,6 +106,7 @@ class BSDSpecificTestCase(unittest.TestCase):
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)
diff --git a/test/_windows.py b/test/_windows.py
index 9c07142a..969cc894 100644
--- a/test/_windows.py
+++ b/test/_windows.py
@@ -29,7 +29,7 @@ except ImportError:
from psutil._compat import PY3, callable, long
from psutil._pswindows import ACCESS_DENIED_SET
-import _psutil_windows
+import psutil._psutil_windows as _psutil_windows
import psutil
@@ -165,7 +165,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
# --- psutil namespace functions and constants tests
- @unittest.skipUnless(hasattr(os, 'NUMBER_OF_PROCESSORS'),
+ @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'])
@@ -289,8 +289,8 @@ class TestDualProcessImplementation(unittest.TestCase):
('proc_cpu_times', 0.2),
('proc_create_time', 0.5),
('proc_num_handles', 1), # 1 because impl #1 opens a handle
- ('proc_io_counters', 0),
('proc_memory_info', 1024), # KB
+ ('proc_io_counters', 0),
]
def test_compare_values(self):
@@ -370,7 +370,7 @@ class TestDualProcessImplementation(unittest.TestCase):
self.assertRaises(psutil.NoSuchProcess, meth, ZOMBIE_PID)
-def test_main():
+def main():
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
test_suite.addTest(unittest.makeSuite(TestDualProcessImplementation))
@@ -378,5 +378,5 @@ def test_main():
return result.wasSuccessful()
if __name__ == '__main__':
- if not test_main():
+ if not main():
sys.exit(1)
diff --git a/test/test_memory_leaks.py b/test/test_memory_leaks.py
index 488ac621..1441daa1 100644
--- a/test/test_memory_leaks.py
+++ b/test/test_memory_leaks.py
@@ -17,11 +17,6 @@ import sys
import threading
import time
-if sys.version_info < (2, 7):
- import unittest2 as unittest # https://pypi.python.org/pypi/unittest2
-else:
- import unittest
-
import psutil
import psutil._common
@@ -31,6 +26,11 @@ from test_psutil import (WINDOWS, POSIX, OSX, LINUX, SUNOS, BSD, TESTFN,
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
diff --git a/test/test_psutil.py b/test/test_psutil.py
index fad37c8c..efbcead1 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -47,14 +47,19 @@ try:
except ImportError:
ipaddress = None
+try:
+ import enum # python >= 3.4
+except ImportError:
+ enum = None
+
+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
-import psutil
-from psutil._compat import PY3, callable, long, unicode
-
# ===================================================================
# --- Constants
@@ -282,18 +287,20 @@ def reap_children(search_all=False):
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 is not None:
+ if ipaddress:
if not PY3:
addr = unicode(addr)
ipaddress.IPv4Address(addr)
elif family == AF_INET6:
assert isinstance(addr, str), addr
- if ipaddress is not None:
+ if ipaddress:
if not PY3:
addr = unicode(addr)
ipaddress.IPv6Address(addr)
@@ -542,9 +549,10 @@ class TestSystemAPIs(unittest.TestCase):
self.assertEqual(len(list(psutil.process_iter())), len(psutil.pids()))
def test_wait_procs(self):
- l = []
- callback = lambda p: l.append(p.pid)
+ def callback(p):
+ l.append(p.pid)
+ l = []
sproc1 = get_test_subprocess()
sproc2 = get_test_subprocess()
sproc3 = get_test_subprocess()
@@ -1003,6 +1011,7 @@ class TestSystemAPIs(unittest.TestCase):
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):
@@ -1073,7 +1082,8 @@ class TestSystemAPIs(unittest.TestCase):
check_ip_address(ip, addr.family)
if BSD or OSX or SUNOS:
- self.assertEqual(psutil.AF_LINK, socket.AF_LINK)
+ 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:
@@ -1705,7 +1715,7 @@ class TestProcess(unittest.TestCase):
assert os.path.isfile(file), file
# another process
- cmdline = "import time; f = open(r'%s', 'r'); time.sleep(2);" % TESTFN
+ cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN
sproc = get_test_subprocess([PYTHON, "-c", cmdline], wait=True)
p = psutil.Process(sproc.pid)
@@ -1983,9 +1993,9 @@ class TestProcess(unittest.TestCase):
# 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(2);'];"
+ s += "cmd = [PYTHON, '-c', 'import time; time.sleep(4);'];"
s += "subprocess.Popen(cmd);"
- s += "time.sleep(2);"
+ s += "time.sleep(4);"
get_test_subprocess(cmd=[PYTHON, "-c", s])
p = psutil.Process()
self.assertEqual(len(p.children(recursive=False)), 1)
@@ -2737,7 +2747,7 @@ class TestExampleScripts(unittest.TestCase):
self.assertIn(str(os.getpid()), output)
-def test_main():
+def main():
tests = []
test_suite = unittest.TestSuite()
tests.append(TestSystemAPIs)
@@ -2774,5 +2784,5 @@ def test_main():
return result.wasSuccessful()
if __name__ == '__main__':
- if not test_main():
+ if not main():
sys.exit(1)
diff --git a/tox.ini b/tox.ini
index dcbabeb4..d5ee51ae 100644
--- a/tox.ini
+++ b/tox.ini
@@ -18,6 +18,7 @@ commands =
git ls-files | grep \\.py$ | xargs flake8
# suppress "WARNING: 'git' command found but not installed in testenv
whitelist_externals = git
+usedevelop = True
[testenv:py26]
deps =