mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-31 21:41:33 +00:00
Vendorizing psutil.
This commit is contained in:
parent
a424ded4a1
commit
d104c8c62e
34 changed files with 13070 additions and 2 deletions
|
@ -1,4 +1,4 @@
|
|||
import psutil
|
||||
from vendor import psutil
|
||||
import math
|
||||
|
||||
GIGS_OF_MEMORY = psutil.TOTAL_PHYMEM/1024/1024/1024.
|
||||
|
|
|
@ -22,7 +22,6 @@ lxml==3.1.0
|
|||
mongoengine==0.8.2
|
||||
nltk==2.0.4
|
||||
oauth2==1.5.211
|
||||
psutil==0.6.1
|
||||
pyes==0.19.1
|
||||
pyelasticsearch==0.5
|
||||
pyflakes==0.6.1
|
||||
|
|
1195
vendor/psutil/__init__.py
vendored
Normal file
1195
vendor/psutil/__init__.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
193
vendor/psutil/_common.py
vendored
Normal file
193
vendor/psutil/_common.py
vendored
Normal file
|
@ -0,0 +1,193 @@
|
|||
#/usr/bin/env python
|
||||
#
|
||||
#$Id: _common.py 1524 2012-08-16 15:06:32Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Common objects shared by all _ps* modules."""
|
||||
|
||||
from __future__ import division
|
||||
import sys
|
||||
import os
|
||||
import stat
|
||||
import errno
|
||||
import warnings
|
||||
|
||||
from psutil._compat import namedtuple, long, wraps
|
||||
|
||||
# --- 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
|
||||
|
||||
class constant(int):
|
||||
"""A constant type; overrides base int to provide a useful name on str()."""
|
||||
|
||||
def __new__(cls, value, name, doc=None):
|
||||
inst = super(constant, cls).__new__(cls, value)
|
||||
inst._name = name
|
||||
if doc is not None:
|
||||
inst.__doc__ = doc
|
||||
return inst
|
||||
|
||||
def __str__(self):
|
||||
return self._name
|
||||
|
||||
def __eq__(self, other):
|
||||
# Use both int or str values when comparing for equality
|
||||
# (useful for serialization):
|
||||
# >>> st = constant(0, "running")
|
||||
# >>> st == 0
|
||||
# True
|
||||
# >>> st == 'running'
|
||||
# True
|
||||
if isinstance(other, int):
|
||||
return int(self) == other
|
||||
if isinstance(other, long):
|
||||
return long(self) == other
|
||||
if isinstance(other, str):
|
||||
return self._name == other
|
||||
return False
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
def memoize(f):
|
||||
"""A simple memoize decorator for functions."""
|
||||
cache= {}
|
||||
def memf(*x):
|
||||
if x not in cache:
|
||||
cache[x] = f(*x)
|
||||
return cache[x]
|
||||
return memf
|
||||
|
||||
class cached_property(object):
|
||||
"""A memoize decorator for class properties."""
|
||||
enabled = True
|
||||
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __get__(self, instance, type):
|
||||
ret = self.func(instance)
|
||||
if self.enabled:
|
||||
instance.__dict__[self.func.__name__] = ret
|
||||
return ret
|
||||
|
||||
# http://goo.gl/jYLvf
|
||||
def deprecated(replacement=None):
|
||||
"""A decorator which can be used to mark functions as deprecated."""
|
||||
def outer(fun):
|
||||
msg = "psutil.%s is deprecated" % fun.__name__
|
||||
if replacement is not None:
|
||||
msg += "; use %s instead" % replacement
|
||||
if fun.__doc__ is None:
|
||||
fun.__doc__ = msg
|
||||
|
||||
@wraps(fun)
|
||||
def inner(*args, **kwargs):
|
||||
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
|
||||
return fun(*args, **kwargs)
|
||||
|
||||
return inner
|
||||
return outer
|
||||
|
||||
|
||||
def 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:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in (errno.EPERM, errno.EACCES):
|
||||
raise
|
||||
return False
|
||||
else:
|
||||
return stat.S_ISREG(st.st_mode)
|
||||
|
||||
|
||||
# --- constants
|
||||
|
||||
STATUS_RUNNING = constant(0, "running")
|
||||
STATUS_SLEEPING = constant(1, "sleeping")
|
||||
STATUS_DISK_SLEEP = constant(2, "disk sleep")
|
||||
STATUS_STOPPED = constant(3, "stopped")
|
||||
STATUS_TRACING_STOP = constant(4, "tracing stop")
|
||||
STATUS_ZOMBIE = constant(5, "zombie")
|
||||
STATUS_DEAD = constant(6, "dead")
|
||||
STATUS_WAKE_KILL = constant(7, "wake kill")
|
||||
STATUS_WAKING = constant(8, "waking")
|
||||
STATUS_IDLE = constant(9, "idle") # BSD
|
||||
STATUS_LOCKED = constant(10, "locked") # BSD
|
||||
STATUS_WAITING = constant(11, "waiting") # BSD
|
||||
|
||||
# --- Process.get_connections() 'kind' parameter mapping
|
||||
|
||||
import socket
|
||||
from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
|
||||
AF_INET6 = getattr(socket, 'AF_INET6', None)
|
||||
AF_UNIX = getattr(socket, 'AF_UNIX', None)
|
||||
|
||||
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, socket
|
||||
|
||||
# --- namedtuples
|
||||
|
||||
# system
|
||||
nt_sys_cputimes = namedtuple('cputimes', 'user nice system idle iowait irq softirq')
|
||||
nt_sysmeminfo = namedtuple('usage', 'total used free percent')
|
||||
# XXX - would 'available' be better than 'free' as for virtual_memory() nt?
|
||||
nt_swapmeminfo = namedtuple('swap', 'total used free percent sin sout')
|
||||
nt_diskinfo = namedtuple('usage', 'total used free percent')
|
||||
nt_partition = namedtuple('partition', 'device mountpoint fstype opts')
|
||||
nt_net_iostat = namedtuple('iostat',
|
||||
'bytes_sent bytes_recv packets_sent packets_recv errin errout dropin dropout')
|
||||
nt_disk_iostat = namedtuple('iostat', 'read_count write_count read_bytes write_bytes read_time write_time')
|
||||
nt_user = namedtuple('user', 'name terminal host started')
|
||||
|
||||
# processes
|
||||
nt_meminfo = namedtuple('meminfo', 'rss vms')
|
||||
nt_cputimes = namedtuple('cputimes', 'user system')
|
||||
nt_openfile = namedtuple('openfile', 'path fd')
|
||||
nt_connection = namedtuple('connection', 'fd family type local_address remote_address status')
|
||||
nt_thread = namedtuple('thread', 'id user_time system_time')
|
||||
nt_uids = namedtuple('user', 'real effective saved')
|
||||
nt_gids = namedtuple('group', 'real effective saved')
|
||||
nt_io = namedtuple('io', 'read_count write_count read_bytes write_bytes')
|
||||
nt_ionice = namedtuple('ionice', 'ioclass value')
|
||||
nt_ctxsw = namedtuple('amount', 'voluntary involuntary')
|
270
vendor/psutil/_compat.py
vendored
Normal file
270
vendor/psutil/_compat.py
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: _compat.py 1524 2012-08-16 15:06:32Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Module which provides compatibility with older Python versions."""
|
||||
|
||||
__all__ = ["PY3", "int", "long", "xrange", "exec_", "callable",
|
||||
"namedtuple", "property", "defaultdict"]
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
# --- python 2/3 compatibility layer
|
||||
|
||||
PY3 = sys.version_info >= (3,)
|
||||
|
||||
try:
|
||||
import __builtin__
|
||||
except ImportError:
|
||||
import builtins as __builtin__ # py3
|
||||
|
||||
if PY3:
|
||||
int = int
|
||||
long = int
|
||||
xrange = range
|
||||
exec_ = getattr(__builtin__, "exec")
|
||||
print_ = getattr(__builtin__, "print")
|
||||
else:
|
||||
int = int
|
||||
long = long
|
||||
xrange = xrange
|
||||
|
||||
def exec_(code, globs=None, locs=None):
|
||||
if globs is None:
|
||||
frame = _sys._getframe(1)
|
||||
globs = frame.f_globals
|
||||
if locs is None:
|
||||
locs = frame.f_locals
|
||||
del frame
|
||||
elif locs is None:
|
||||
locs = globs
|
||||
exec("""exec code in globs, locs""")
|
||||
|
||||
def print_(s):
|
||||
sys.stdout.write(s + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
# removed in 3.0, reintroduced in 3.2
|
||||
try:
|
||||
callable = callable
|
||||
except Exception:
|
||||
def callable(obj):
|
||||
for klass in type(obj).__mro__:
|
||||
if "__call__" in klass.__dict__:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# --- stdlib additions
|
||||
|
||||
try:
|
||||
from collections import namedtuple
|
||||
except ImportError:
|
||||
from operator import itemgetter as _itemgetter
|
||||
from keyword import iskeyword as _iskeyword
|
||||
import sys as _sys
|
||||
|
||||
def namedtuple(typename, field_names, verbose=False, rename=False):
|
||||
"""A collections.namedtuple implementation written in Python
|
||||
to support Python versions < 2.6.
|
||||
|
||||
Taken from: http://code.activestate.com/recipes/500261/
|
||||
"""
|
||||
# Parse and validate the field names. Validation serves two
|
||||
# purposes, generating informative error messages and preventing
|
||||
# template injection attacks.
|
||||
if isinstance(field_names, basestring):
|
||||
# names separated by whitespace and/or commas
|
||||
field_names = field_names.replace(',', ' ').split()
|
||||
field_names = tuple(map(str, field_names))
|
||||
if rename:
|
||||
names = list(field_names)
|
||||
seen = set()
|
||||
for i, name in enumerate(names):
|
||||
if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
|
||||
or not name or name[0].isdigit() or name.startswith('_')
|
||||
or name in seen):
|
||||
names[i] = '_%d' % i
|
||||
seen.add(name)
|
||||
field_names = tuple(names)
|
||||
for name in (typename,) + field_names:
|
||||
if not min(c.isalnum() or c=='_' for c in name):
|
||||
raise ValueError('Type names and field names can only contain ' \
|
||||
'alphanumeric characters and underscores: %r'
|
||||
% name)
|
||||
if _iskeyword(name):
|
||||
raise ValueError('Type names and field names cannot be a keyword: %r' \
|
||||
% name)
|
||||
if name[0].isdigit():
|
||||
raise ValueError('Type names and field names cannot start with a ' \
|
||||
'number: %r' % name)
|
||||
seen_names = set()
|
||||
for name in field_names:
|
||||
if name.startswith('_') and not rename:
|
||||
raise ValueError('Field names cannot start with an underscore: %r'
|
||||
% name)
|
||||
if name in seen_names:
|
||||
raise ValueError('Encountered duplicate field name: %r' % name)
|
||||
seen_names.add(name)
|
||||
|
||||
# Create and fill-in the class template
|
||||
numfields = len(field_names)
|
||||
# tuple repr without parens or quotes
|
||||
argtxt = repr(field_names).replace("'", "")[1:-1]
|
||||
reprtxt = ', '.join('%s=%%r' % name for name in field_names)
|
||||
template = '''class %(typename)s(tuple):
|
||||
'%(typename)s(%(argtxt)s)' \n
|
||||
__slots__ = () \n
|
||||
_fields = %(field_names)r \n
|
||||
def __new__(_cls, %(argtxt)s):
|
||||
return _tuple.__new__(_cls, (%(argtxt)s)) \n
|
||||
@classmethod
|
||||
def _make(cls, iterable, new=tuple.__new__, len=len):
|
||||
'Make a new %(typename)s object from a sequence or iterable'
|
||||
result = new(cls, iterable)
|
||||
if len(result) != %(numfields)d:
|
||||
raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
|
||||
return result \n
|
||||
def __repr__(self):
|
||||
return '%(typename)s(%(reprtxt)s)' %% self \n
|
||||
def _asdict(self):
|
||||
'Return a new dict which maps field names to their values'
|
||||
return dict(zip(self._fields, self)) \n
|
||||
def _replace(_self, **kwds):
|
||||
'Return a new %(typename)s object replacing specified fields with new values'
|
||||
result = _self._make(map(kwds.pop, %(field_names)r, _self))
|
||||
if kwds:
|
||||
raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
|
||||
return result \n
|
||||
def __getnewargs__(self):
|
||||
return tuple(self) \n\n''' % locals()
|
||||
for i, name in enumerate(field_names):
|
||||
template += ' %s = _property(_itemgetter(%d))\n' % (name, i)
|
||||
if verbose:
|
||||
sys.stdout.write(template + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
# Execute the template string in a temporary namespace
|
||||
namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
|
||||
_property=property, _tuple=tuple)
|
||||
try:
|
||||
exec_(template, namespace)
|
||||
except SyntaxError:
|
||||
e = sys.exc_info()[1]
|
||||
raise SyntaxError(e.message + ':\n' + template)
|
||||
result = namespace[typename]
|
||||
|
||||
# For pickling to work, the __module__ variable needs to be set
|
||||
# to the frame where the named tuple is created. Bypass this
|
||||
# step in enviroments where sys._getframe is not defined (Jython
|
||||
# for example) or sys._getframe is not defined for arguments
|
||||
# greater than 0 (IronPython).
|
||||
try:
|
||||
result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
|
||||
except (AttributeError, ValueError):
|
||||
pass
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# hack to support property.setter/deleter on python < 2.6
|
||||
# http://docs.python.org/library/functions.html?highlight=property#property
|
||||
if hasattr(property, 'setter'):
|
||||
property = property
|
||||
else:
|
||||
class property(__builtin__.property):
|
||||
__metaclass__ = type
|
||||
|
||||
def __init__(self, fget, *args, **kwargs):
|
||||
super(property, self).__init__(fget, *args, **kwargs)
|
||||
self.__doc__ = fget.__doc__
|
||||
|
||||
def getter(self, method):
|
||||
return property(method, self.fset, self.fdel)
|
||||
|
||||
def setter(self, method):
|
||||
return property(self.fget, method, self.fdel)
|
||||
|
||||
def deleter(self, method):
|
||||
return property(self.fget, self.fset, method)
|
||||
|
||||
|
||||
# py 2.5 collections.defauldict
|
||||
# Taken from:
|
||||
# http://code.activestate.com/recipes/523034-emulate-collectionsdefaultdict/
|
||||
# credits: Jason Kirtland
|
||||
try:
|
||||
from collections import defaultdict
|
||||
except ImportError:
|
||||
class defaultdict(dict):
|
||||
|
||||
def __init__(self, default_factory=None, *a, **kw):
|
||||
if (default_factory is not None and
|
||||
not hasattr(default_factory, '__call__')):
|
||||
raise TypeError('first argument must be callable')
|
||||
dict.__init__(self, *a, **kw)
|
||||
self.default_factory = default_factory
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return dict.__getitem__(self, key)
|
||||
except KeyError:
|
||||
return self.__missing__(key)
|
||||
|
||||
def __missing__(self, key):
|
||||
if self.default_factory is None:
|
||||
raise KeyError(key)
|
||||
self[key] = value = self.default_factory()
|
||||
return value
|
||||
|
||||
def __reduce__(self):
|
||||
if self.default_factory is None:
|
||||
args = tuple()
|
||||
else:
|
||||
args = self.default_factory,
|
||||
return type(self), args, None, None, self.items()
|
||||
|
||||
def copy(self):
|
||||
return self.__copy__()
|
||||
|
||||
def __copy__(self):
|
||||
return type(self)(self.default_factory, self)
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
import copy
|
||||
return type(self)(self.default_factory,
|
||||
copy.deepcopy(self.items()))
|
||||
|
||||
def __repr__(self):
|
||||
return 'defaultdict(%s, %s)' % (self.default_factory,
|
||||
dict.__repr__(self))
|
||||
|
||||
|
||||
# py 2.5 functools.wraps
|
||||
try:
|
||||
from functools import wraps
|
||||
except ImportError:
|
||||
def wraps(original):
|
||||
def inner(fn):
|
||||
# see functools.WRAPPER_ASSIGNMENTS
|
||||
for attribute in ['__module__',
|
||||
'__name__',
|
||||
'__doc__'
|
||||
]:
|
||||
setattr(fn, attribute, getattr(original, attribute))
|
||||
# see functools.WRAPPER_UPDATES
|
||||
for attribute in ['__dict__',
|
||||
]:
|
||||
if hasattr(fn, attribute):
|
||||
getattr(fn, attribute).update(getattr(original, attribute))
|
||||
else:
|
||||
setattr(fn, attribute,
|
||||
getattr(original, attribute).copy())
|
||||
return fn
|
||||
return inner
|
328
vendor/psutil/_psbsd.py
vendored
Normal file
328
vendor/psutil/_psbsd.py
vendored
Normal file
|
@ -0,0 +1,328 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: _psbsd.py 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""FreeBSD platform implementation."""
|
||||
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
|
||||
import _psutil_bsd
|
||||
import _psutil_posix
|
||||
from psutil import _psposix
|
||||
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
|
||||
from psutil._compat import namedtuple
|
||||
from psutil._common import *
|
||||
|
||||
__extra__all__ = []
|
||||
|
||||
# --- constants
|
||||
|
||||
NUM_CPUS = _psutil_bsd.get_num_cpus()
|
||||
BOOT_TIME = _psutil_bsd.get_system_boot_time()
|
||||
TOTAL_PHYMEM = _psutil_bsd.get_virtual_mem()[0]
|
||||
_TERMINAL_MAP = _psposix._get_terminal_map()
|
||||
_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
|
||||
_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle irq')
|
||||
|
||||
# --- public functions
|
||||
|
||||
nt_virtmem_info = namedtuple('vmem', ' '.join([
|
||||
# all platforms
|
||||
'total', 'available', 'percent', 'used', 'free',
|
||||
# FreeBSD specific
|
||||
'active',
|
||||
'inactive',
|
||||
'buffers',
|
||||
'cached',
|
||||
'shared',
|
||||
'wired']))
|
||||
|
||||
def virtual_memory():
|
||||
"""System virtual memory as a namedutple."""
|
||||
mem = _psutil_bsd.get_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 nt_virtmem_info(total, avail, percent, used, free,
|
||||
active, inactive, buffers, cached, shared, wired)
|
||||
|
||||
def swap_memory():
|
||||
"""System swap memory as (total, used, free, sin, sout) namedtuple."""
|
||||
total, used, free, sin, sout = \
|
||||
[x * _PAGESIZE for x in _psutil_bsd.get_swap_mem()]
|
||||
percent = usage_percent(used, total, _round=1)
|
||||
return nt_swapmeminfo(total, used, free, percent, sin, sout)
|
||||
|
||||
def get_system_cpu_times():
|
||||
"""Return system per-CPU times as a named tuple"""
|
||||
user, nice, system, idle, irq = _psutil_bsd.get_system_cpu_times()
|
||||
return _cputimes_ntuple(user, nice, system, idle, irq)
|
||||
|
||||
def get_system_per_cpu_times():
|
||||
"""Return system CPU times as a named tuple"""
|
||||
ret = []
|
||||
for cpu_t in _psutil_bsd.get_system_per_cpu_times():
|
||||
user, nice, system, idle, irq = cpu_t
|
||||
item = _cputimes_ntuple(user, nice, system, idle, irq)
|
||||
ret.append(item)
|
||||
return ret
|
||||
|
||||
# XXX
|
||||
# Ok, this is very dirty.
|
||||
# On FreeBSD < 8 we cannot gather per-cpu information, see:
|
||||
# http://code.google.com/p/psutil/issues/detail?id=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
|
||||
if not hasattr(_psutil_bsd, "get_system_per_cpu_times"):
|
||||
def get_system_per_cpu_times():
|
||||
if NUM_CPUS == 1:
|
||||
return [get_system_cpu_times]
|
||||
if get_system_per_cpu_times.__called__:
|
||||
raise NotImplementedError("supported only starting from FreeBSD 8")
|
||||
get_system_per_cpu_times.__called__ = True
|
||||
return [get_system_cpu_times]
|
||||
get_system_per_cpu_times.__called__ = False
|
||||
|
||||
def disk_partitions(all=False):
|
||||
retlist = []
|
||||
partitions = _psutil_bsd.get_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 = nt_partition(device, mountpoint, fstype, opts)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
def get_system_users():
|
||||
retlist = []
|
||||
rawlist = _psutil_bsd.get_system_users()
|
||||
for item in rawlist:
|
||||
user, tty, hostname, tstamp = item
|
||||
if tty == '~':
|
||||
continue # reboot or shutdown
|
||||
nt = nt_user(user, tty or None, hostname, tstamp)
|
||||
retlist.append(nt)
|
||||
return retlist
|
||||
|
||||
get_pid_list = _psutil_bsd.get_pid_list
|
||||
pid_exists = _psposix.pid_exists
|
||||
get_disk_usage = _psposix.get_disk_usage
|
||||
network_io_counters = _psutil_bsd.get_network_io_counters
|
||||
disk_io_counters = _psutil_bsd.get_disk_io_counters
|
||||
|
||||
|
||||
def wrap_exceptions(method):
|
||||
"""Call method(self, pid) into a try/except clause so that if an
|
||||
OSError "No such process" exception is raised we assume the process
|
||||
has died and raise psutil.NoSuchProcess instead.
|
||||
"""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
return method(self, *args, **kwargs)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno == errno.ESRCH:
|
||||
raise NoSuchProcess(self.pid, self._process_name)
|
||||
if err.errno in (errno.EPERM, errno.EACCES):
|
||||
raise AccessDenied(self.pid, self._process_name)
|
||||
raise
|
||||
return wrapper
|
||||
|
||||
_status_map = {
|
||||
_psutil_bsd.SSTOP : STATUS_STOPPED,
|
||||
_psutil_bsd.SSLEEP : STATUS_SLEEPING,
|
||||
_psutil_bsd.SRUN : STATUS_RUNNING,
|
||||
_psutil_bsd.SIDL : STATUS_IDLE,
|
||||
_psutil_bsd.SWAIT : STATUS_WAITING,
|
||||
_psutil_bsd.SLOCK : STATUS_LOCKED,
|
||||
_psutil_bsd.SZOMB : STATUS_ZOMBIE,
|
||||
}
|
||||
|
||||
|
||||
class Process(object):
|
||||
"""Wrapper class around underlying C implementation."""
|
||||
|
||||
__slots__ = ["pid", "_process_name"]
|
||||
|
||||
def __init__(self, pid):
|
||||
self.pid = pid
|
||||
self._process_name = None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_name(self):
|
||||
"""Return process name as a string of limited len (15)."""
|
||||
return _psutil_bsd.get_process_name(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_exe(self):
|
||||
"""Return process executable pathname."""
|
||||
return _psutil_bsd.get_process_exe(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cmdline(self):
|
||||
"""Return process cmdline as a list of arguments."""
|
||||
return _psutil_bsd.get_process_cmdline(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_terminal(self):
|
||||
tty_nr = _psutil_bsd.get_process_tty_nr(self.pid)
|
||||
try:
|
||||
return _TERMINAL_MAP[tty_nr]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_ppid(self):
|
||||
"""Return process parent pid."""
|
||||
return _psutil_bsd.get_process_ppid(self.pid)
|
||||
|
||||
# XXX - available on FreeBSD >= 8 only
|
||||
if hasattr(_psutil_bsd, "get_process_cwd"):
|
||||
@wrap_exceptions
|
||||
def get_process_cwd(self):
|
||||
"""Return process current working directory."""
|
||||
# sometimes we get an empty string, in which case we turn
|
||||
# it into None
|
||||
return _psutil_bsd.get_process_cwd(self.pid) or None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_uids(self):
|
||||
"""Return real, effective and saved user ids."""
|
||||
real, effective, saved = _psutil_bsd.get_process_uids(self.pid)
|
||||
return nt_uids(real, effective, saved)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_gids(self):
|
||||
"""Return real, effective and saved group ids."""
|
||||
real, effective, saved = _psutil_bsd.get_process_gids(self.pid)
|
||||
return nt_gids(real, effective, saved)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_cpu_times(self):
|
||||
"""return a tuple containing process user/kernel time."""
|
||||
user, system = _psutil_bsd.get_process_cpu_times(self.pid)
|
||||
return nt_cputimes(user, system)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_memory_info(self):
|
||||
"""Return a tuple with the process' RSS and VMS size."""
|
||||
rss, vms = _psutil_bsd.get_process_memory_info(self.pid)[:2]
|
||||
return nt_meminfo(rss, vms)
|
||||
|
||||
_nt_ext_mem = namedtuple('meminfo', 'rss vms text data stack')
|
||||
|
||||
@wrap_exceptions
|
||||
def get_ext_memory_info(self):
|
||||
return self._nt_ext_mem(*_psutil_bsd.get_process_memory_info(self.pid))
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_create_time(self):
|
||||
"""Return the start time of the process as a number of seconds since
|
||||
the epoch."""
|
||||
return _psutil_bsd.get_process_create_time(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_num_threads(self):
|
||||
"""Return the number of threads belonging to the process."""
|
||||
return _psutil_bsd.get_process_num_threads(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_ctx_switches(self):
|
||||
return nt_ctxsw(*_psutil_bsd.get_process_num_ctx_switches(self.pid))
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_fds(self):
|
||||
"""Return the number of file descriptors opened by this process."""
|
||||
return _psutil_bsd.get_process_num_fds(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_threads(self):
|
||||
"""Return the number of threads belonging to the process."""
|
||||
rawlist = _psutil_bsd.get_process_threads(self.pid)
|
||||
retlist = []
|
||||
for thread_id, utime, stime in rawlist:
|
||||
ntuple = nt_thread(thread_id, utime, stime)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
@wrap_exceptions
|
||||
def get_open_files(self):
|
||||
"""Return files opened by process as a list of namedtuples."""
|
||||
# XXX - C implementation available on FreeBSD >= 8 only
|
||||
# else fallback on lsof parser
|
||||
if hasattr(_psutil_bsd, "get_process_open_files"):
|
||||
rawlist = _psutil_bsd.get_process_open_files(self.pid)
|
||||
return [nt_openfile(path, fd) for path, fd in rawlist]
|
||||
else:
|
||||
lsof = _psposix.LsofParser(self.pid, self._process_name)
|
||||
return lsof.get_process_open_files()
|
||||
|
||||
@wrap_exceptions
|
||||
def get_connections(self, kind='inet'):
|
||||
"""Return etwork connections opened by a process as a list of
|
||||
namedtuples.
|
||||
"""
|
||||
if kind not in conn_tmap:
|
||||
raise ValueError("invalid %r kind argument; choose between %s"
|
||||
% (kind, ', '.join([repr(x) for x in conn_tmap])))
|
||||
families, types = conn_tmap[kind]
|
||||
ret = _psutil_bsd.get_process_connections(self.pid, families, types)
|
||||
return [nt_connection(*conn) for conn in ret]
|
||||
|
||||
@wrap_exceptions
|
||||
def process_wait(self, timeout=None):
|
||||
try:
|
||||
return _psposix.wait_pid(self.pid, timeout)
|
||||
except TimeoutExpired:
|
||||
raise TimeoutExpired(self.pid, self._process_name)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_nice(self):
|
||||
return _psutil_posix.getpriority(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def set_process_nice(self, value):
|
||||
return _psutil_posix.setpriority(self.pid, value)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_status(self):
|
||||
code = _psutil_bsd.get_process_status(self.pid)
|
||||
if code in _status_map:
|
||||
return _status_map[code]
|
||||
return constant(-1, "?")
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_io_counters(self):
|
||||
rc, wc, rb, wb = _psutil_bsd.get_process_io_counters(self.pid)
|
||||
return nt_io(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')
|
||||
|
||||
@wrap_exceptions
|
||||
def get_memory_maps(self):
|
||||
return _psutil_bsd.get_process_memory_maps(self.pid)
|
||||
|
||||
# FreeBSD < 8 does not support kinfo_getfile() and kinfo_getvmmap()
|
||||
if not hasattr(_psutil_bsd, 'get_process_open_files'):
|
||||
def _not_implemented(self):
|
||||
raise NotImplementedError("supported only starting from FreeBSD 8")
|
||||
get_open_files = _not_implemented
|
||||
get_process_cwd = _not_implemented
|
||||
get_memory_maps = _not_implemented
|
||||
get_num_fds = _not_implemented
|
1011
vendor/psutil/_pslinux.py
vendored
Executable file
1011
vendor/psutil/_pslinux.py
vendored
Executable file
File diff suppressed because it is too large
Load diff
423
vendor/psutil/_psmswindows.py
vendored
Normal file
423
vendor/psutil/_psmswindows.py
vendored
Normal file
|
@ -0,0 +1,423 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: _psmswindows.py 1514 2012-08-14 11:16:56Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Windows platform implementation."""
|
||||
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
|
||||
import _psutil_mswindows
|
||||
from _psutil_mswindows import ERROR_ACCESS_DENIED
|
||||
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
|
||||
from psutil._common import *
|
||||
from psutil._compat import PY3, xrange, long
|
||||
|
||||
# Windows specific extended namespace
|
||||
__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
|
||||
"HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
|
||||
"NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS"]
|
||||
|
||||
|
||||
# --- module level constants (gets pushed up to psutil module)
|
||||
|
||||
NUM_CPUS = _psutil_mswindows.get_num_cpus()
|
||||
BOOT_TIME = _psutil_mswindows.get_system_uptime()
|
||||
TOTAL_PHYMEM = _psutil_mswindows.get_virtual_mem()[0]
|
||||
WAIT_TIMEOUT = 0x00000102 # 258 in decimal
|
||||
ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED])
|
||||
|
||||
# process priority constants:
|
||||
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
|
||||
from _psutil_mswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
BELOW_NORMAL_PRIORITY_CLASS,
|
||||
HIGH_PRIORITY_CLASS,
|
||||
IDLE_PRIORITY_CLASS,
|
||||
NORMAL_PRIORITY_CLASS,
|
||||
REALTIME_PRIORITY_CLASS,
|
||||
INFINITE)
|
||||
|
||||
@memoize
|
||||
def _win32_QueryDosDevice(s):
|
||||
return _psutil_mswindows.win32_QueryDosDevice(s)
|
||||
|
||||
def _convert_raw_path(s):
|
||||
# convert paths using native DOS format like:
|
||||
# "\Device\HarddiskVolume1\Windows\systemew\file.txt"
|
||||
# into: "C:\Windows\systemew\file.txt"
|
||||
if PY3 and not isinstance(s, str):
|
||||
s = s.decode('utf8')
|
||||
rawdrive = '\\'.join(s.split('\\')[:3])
|
||||
driveletter = _win32_QueryDosDevice(rawdrive)
|
||||
return os.path.join(driveletter, s[len(rawdrive):])
|
||||
|
||||
|
||||
# --- public functions
|
||||
|
||||
nt_virtmem_info = namedtuple('vmem', ' '.join([
|
||||
# all platforms
|
||||
'total', 'available', 'percent', 'used', 'free']))
|
||||
|
||||
def virtual_memory():
|
||||
"""System virtual memory as a namedtuple."""
|
||||
mem = _psutil_mswindows.get_virtual_mem()
|
||||
totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
|
||||
#
|
||||
total = totphys
|
||||
avail = availphys
|
||||
free = availphys
|
||||
used = total - avail
|
||||
percent = usage_percent((total - avail), total, _round=1)
|
||||
return nt_virtmem_info(total, avail, percent, used, free)
|
||||
|
||||
def swap_memory():
|
||||
"""Swap system memory as a (total, used, free, sin, sout) tuple."""
|
||||
mem = _psutil_mswindows.get_virtual_mem()
|
||||
total = mem[2]
|
||||
free = mem[3]
|
||||
used = total - free
|
||||
percent = usage_percent(used, total, _round=1)
|
||||
return nt_swapmeminfo(total, used, free, percent, 0, 0)
|
||||
|
||||
def get_disk_usage(path):
|
||||
"""Return disk usage associated with path."""
|
||||
try:
|
||||
total, free = _psutil_mswindows.get_disk_usage(path)
|
||||
except WindowsError:
|
||||
err = sys.exc_info()[1]
|
||||
if not os.path.exists(path):
|
||||
raise OSError(errno.ENOENT, "No such file or directory: '%s'" % path)
|
||||
raise
|
||||
used = total - free
|
||||
percent = usage_percent(used, total, _round=1)
|
||||
return nt_diskinfo(total, used, free, percent)
|
||||
|
||||
def disk_partitions(all):
|
||||
"""Return disk partitions."""
|
||||
rawlist = _psutil_mswindows.get_disk_partitions(all)
|
||||
return [nt_partition(*x) for x in rawlist]
|
||||
|
||||
|
||||
_cputimes_ntuple = namedtuple('cputimes', 'user system idle')
|
||||
|
||||
def get_system_cpu_times():
|
||||
"""Return system CPU times as a named tuple."""
|
||||
user, system, idle = 0, 0, 0
|
||||
# computes system global times summing each processor value
|
||||
for cpu_time in _psutil_mswindows.get_system_cpu_times():
|
||||
user += cpu_time[0]
|
||||
system += cpu_time[1]
|
||||
idle += cpu_time[2]
|
||||
return _cputimes_ntuple(user, system, idle)
|
||||
|
||||
def get_system_per_cpu_times():
|
||||
"""Return system per-CPU times as a list of named tuples."""
|
||||
ret = []
|
||||
for cpu_t in _psutil_mswindows.get_system_cpu_times():
|
||||
user, system, idle = cpu_t
|
||||
item = _cputimes_ntuple(user, system, idle)
|
||||
ret.append(item)
|
||||
return ret
|
||||
|
||||
def get_system_users():
|
||||
"""Return currently connected users as a list of namedtuples."""
|
||||
retlist = []
|
||||
rawlist = _psutil_mswindows.get_system_users()
|
||||
for item in rawlist:
|
||||
user, hostname, tstamp = item
|
||||
nt = nt_user(user, None, hostname, tstamp)
|
||||
retlist.append(nt)
|
||||
return retlist
|
||||
|
||||
get_pid_list = _psutil_mswindows.get_pid_list
|
||||
pid_exists = _psutil_mswindows.pid_exists
|
||||
network_io_counters = _psutil_mswindows.get_network_io_counters
|
||||
disk_io_counters = _psutil_mswindows.get_disk_io_counters
|
||||
|
||||
# --- decorator
|
||||
|
||||
def wrap_exceptions(callable):
|
||||
"""Call callable into a try/except clause so that if a
|
||||
WindowsError 5 AccessDenied exception is raised we translate it
|
||||
into psutil.AccessDenied
|
||||
"""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
return callable(self, *args, **kwargs)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
raise AccessDenied(self.pid, self._process_name)
|
||||
if err.errno == errno.ESRCH:
|
||||
raise NoSuchProcess(self.pid, self._process_name)
|
||||
raise
|
||||
return wrapper
|
||||
|
||||
|
||||
class Process(object):
|
||||
"""Wrapper class around underlying C implementation."""
|
||||
|
||||
__slots__ = ["pid", "_process_name"]
|
||||
|
||||
def __init__(self, pid):
|
||||
self.pid = pid
|
||||
self._process_name = None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_name(self):
|
||||
"""Return process name as a string of limited len (15)."""
|
||||
return _psutil_mswindows.get_process_name(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_exe(self):
|
||||
# Note: os.path.exists(path) may return False even if the file
|
||||
# is there, see:
|
||||
# http://stackoverflow.com/questions/3112546/os-path-exists-lies
|
||||
return _convert_raw_path(_psutil_mswindows.get_process_exe(self.pid))
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cmdline(self):
|
||||
"""Return process cmdline as a list of arguments."""
|
||||
return _psutil_mswindows.get_process_cmdline(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_ppid(self):
|
||||
"""Return process parent pid."""
|
||||
return _psutil_mswindows.get_process_ppid(self.pid)
|
||||
|
||||
def _get_raw_meminfo(self):
|
||||
try:
|
||||
return _psutil_mswindows.get_process_memory_info(self.pid)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
return _psutil_mswindows.get_process_memory_info_2(self.pid)
|
||||
raise
|
||||
|
||||
@wrap_exceptions
|
||||
def get_memory_info(self):
|
||||
"""Returns a tuple or RSS/VMS memory usage in bytes."""
|
||||
# on Windows RSS == WorkingSetSize and VSM == PagefileUsage
|
||||
# fields of PROCESS_MEMORY_COUNTERS struct:
|
||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms684877(v=vs.85).aspx
|
||||
t = self._get_raw_meminfo()
|
||||
return nt_meminfo(t[2], t[7])
|
||||
|
||||
_nt_ext_mem = namedtuple('meminfo',
|
||||
' '.join(['num_page_faults',
|
||||
'peak_wset',
|
||||
'wset',
|
||||
'peak_paged_pool',
|
||||
'paged_pool',
|
||||
'peak_nonpaged_pool',
|
||||
'nonpaged_pool',
|
||||
'pagefile',
|
||||
'peak_pagefile',
|
||||
'private',]))
|
||||
|
||||
@wrap_exceptions
|
||||
def get_ext_memory_info(self):
|
||||
return self._nt_ext_mem(*self._get_raw_meminfo())
|
||||
|
||||
nt_mmap_grouped = namedtuple('mmap', 'path rss')
|
||||
nt_mmap_ext = namedtuple('mmap', 'addr perms path rss')
|
||||
|
||||
def get_memory_maps(self):
|
||||
try:
|
||||
raw = _psutil_mswindows.get_process_memory_maps(self.pid)
|
||||
except OSError:
|
||||
# XXX - can't use wrap_exceptions decorator as we're
|
||||
# returning a generator; probably needs refactoring.
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED):
|
||||
raise AccessDenied(self.pid, self._process_name)
|
||||
if err.errno == errno.ESRCH:
|
||||
raise NoSuchProcess(self.pid, self._process_name)
|
||||
raise
|
||||
else:
|
||||
for addr, perm, path, rss in raw:
|
||||
path = _convert_raw_path(path)
|
||||
addr = hex(addr)
|
||||
yield (addr, perm, path, rss)
|
||||
|
||||
@wrap_exceptions
|
||||
def kill_process(self):
|
||||
"""Terminates the process with the given PID."""
|
||||
return _psutil_mswindows.kill_process(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def process_wait(self, timeout=None):
|
||||
if timeout is None:
|
||||
timeout = INFINITE
|
||||
else:
|
||||
# WaitForSingleObject() expects time in milliseconds
|
||||
timeout = int(timeout * 1000)
|
||||
ret = _psutil_mswindows.process_wait(self.pid, timeout)
|
||||
if ret == WAIT_TIMEOUT:
|
||||
raise TimeoutExpired(self.pid, self._process_name)
|
||||
return ret
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_username(self):
|
||||
"""Return the name of the user that owns the process"""
|
||||
if self.pid in (0, 4):
|
||||
return 'NT AUTHORITY\\SYSTEM'
|
||||
return _psutil_mswindows.get_process_username(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_create_time(self):
|
||||
# special case for kernel process PIDs; return system boot time
|
||||
if self.pid in (0, 4):
|
||||
return BOOT_TIME
|
||||
try:
|
||||
return _psutil_mswindows.get_process_create_time(self.pid)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
return _psutil_mswindows.get_process_create_time_2(self.pid)
|
||||
raise
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_num_threads(self):
|
||||
return _psutil_mswindows.get_process_num_threads(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_threads(self):
|
||||
rawlist = _psutil_mswindows.get_process_threads(self.pid)
|
||||
retlist = []
|
||||
for thread_id, utime, stime in rawlist:
|
||||
ntuple = nt_thread(thread_id, utime, stime)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
@wrap_exceptions
|
||||
def get_cpu_times(self):
|
||||
try:
|
||||
ret = _psutil_mswindows.get_process_cpu_times(self.pid)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
ret = _psutil_mswindows.get_process_cpu_times_2(self.pid)
|
||||
else:
|
||||
raise
|
||||
return nt_cputimes(*ret)
|
||||
|
||||
@wrap_exceptions
|
||||
def suspend_process(self):
|
||||
return _psutil_mswindows.suspend_process(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def resume_process(self):
|
||||
return _psutil_mswindows.resume_process(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cwd(self):
|
||||
if self.pid in (0, 4):
|
||||
raise AccessDenied(self.pid, self._process_name)
|
||||
# return a normalized pathname since the native C function appends
|
||||
# "\\" at the and of the path
|
||||
path = _psutil_mswindows.get_process_cwd(self.pid)
|
||||
return os.path.normpath(path)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_open_files(self):
|
||||
if self.pid in (0, 4):
|
||||
return []
|
||||
retlist = []
|
||||
# Filenames come in in native format like:
|
||||
# "\Device\HarddiskVolume1\Windows\systemew\file.txt"
|
||||
# Convert the first part in the corresponding drive letter
|
||||
# (e.g. "C:\") by using Windows's QueryDosDevice()
|
||||
raw_file_names = _psutil_mswindows.get_process_open_files(self.pid)
|
||||
for file in raw_file_names:
|
||||
file = _convert_raw_path(file)
|
||||
if isfile_strict(file) and file not in retlist:
|
||||
ntuple = nt_openfile(file, -1)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
@wrap_exceptions
|
||||
def get_connections(self, kind='inet'):
|
||||
if kind not in conn_tmap:
|
||||
raise ValueError("invalid %r kind argument; choose between %s"
|
||||
% (kind, ', '.join([repr(x) for x in conn_tmap])))
|
||||
families, types = conn_tmap[kind]
|
||||
ret = _psutil_mswindows.get_process_connections(self.pid, families, types)
|
||||
return [nt_connection(*conn) for conn in ret]
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_nice(self):
|
||||
return _psutil_mswindows.get_process_priority(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def set_process_nice(self, value):
|
||||
return _psutil_mswindows.set_process_priority(self.pid, value)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_io_counters(self):
|
||||
try:
|
||||
ret = _psutil_mswindows.get_process_io_counters(self.pid)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
ret = _psutil_mswindows.get_process_io_counters_2(self.pid)
|
||||
else:
|
||||
raise
|
||||
return nt_io(*ret)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_status(self):
|
||||
suspended = _psutil_mswindows.is_process_suspended(self.pid)
|
||||
if suspended:
|
||||
return STATUS_STOPPED
|
||||
else:
|
||||
return STATUS_RUNNING
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cpu_affinity(self):
|
||||
from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
|
||||
bitmask = _psutil_mswindows.get_process_cpu_affinity(self.pid)
|
||||
return from_bitmask(bitmask)
|
||||
|
||||
@wrap_exceptions
|
||||
def set_process_cpu_affinity(self, value):
|
||||
def to_bitmask(l):
|
||||
if not l:
|
||||
raise ValueError("invalid argument %r" % l)
|
||||
out = 0
|
||||
for b in l:
|
||||
if not isinstance(b, (int, long)) or b < 0:
|
||||
raise ValueError("invalid argument %r" % b)
|
||||
out |= 2**b
|
||||
return out
|
||||
|
||||
# SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
|
||||
# is returned for an invalid CPU but this seems not to be true,
|
||||
# therefore we check CPUs validy beforehand.
|
||||
allcpus = list(range(len(get_system_per_cpu_times())))
|
||||
for cpu in value:
|
||||
if cpu not in allcpus:
|
||||
raise ValueError("invalid CPU %i" % cpu)
|
||||
|
||||
bitmask = to_bitmask(value)
|
||||
_psutil_mswindows.set_process_cpu_affinity(self.pid, bitmask)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_handles(self):
|
||||
try:
|
||||
return _psutil_mswindows.get_process_num_handles(self.pid)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno in ACCESS_DENIED_SET:
|
||||
return _psutil_mswindows.get_process_num_handles_2(self.pid)
|
||||
raise
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_ctx_switches(self):
|
||||
return nt_ctxsw(*_psutil_mswindows.get_process_num_ctx_switches(self.pid))
|
293
vendor/psutil/_psosx.py
vendored
Normal file
293
vendor/psutil/_psosx.py
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: _psosx.py 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""OSX platform implementation."""
|
||||
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
|
||||
import _psutil_osx
|
||||
import _psutil_posix
|
||||
from psutil import _psposix
|
||||
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
|
||||
from psutil._compat import namedtuple
|
||||
from psutil._common import *
|
||||
|
||||
__extra__all__ = []
|
||||
|
||||
# --- constants
|
||||
|
||||
NUM_CPUS = _psutil_osx.get_num_cpus()
|
||||
BOOT_TIME = _psutil_osx.get_system_boot_time()
|
||||
TOTAL_PHYMEM = _psutil_osx.get_virtual_mem()[0]
|
||||
_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
|
||||
_TERMINAL_MAP = _psposix._get_terminal_map()
|
||||
_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle')
|
||||
|
||||
# --- functions
|
||||
|
||||
nt_virtmem_info = namedtuple('vmem', ' '.join([
|
||||
# all platforms
|
||||
'total', 'available', 'percent', 'used', 'free',
|
||||
# OSX specific
|
||||
'active',
|
||||
'inactive',
|
||||
'wired']))
|
||||
|
||||
def virtual_memory():
|
||||
"""System virtual memory as a namedtuple."""
|
||||
total, active, inactive, wired, free = _psutil_osx.get_virtual_mem()
|
||||
avail = inactive + free
|
||||
used = active + inactive + wired
|
||||
percent = usage_percent((total - avail), total, _round=1)
|
||||
return nt_virtmem_info(total, avail, percent, used, free,
|
||||
active, inactive, wired)
|
||||
|
||||
def swap_memory():
|
||||
"""Swap system memory as a (total, used, free, sin, sout) tuple."""
|
||||
total, used, free, sin, sout = _psutil_osx.get_swap_mem()
|
||||
percent = usage_percent(used, total, _round=1)
|
||||
return nt_swapmeminfo(total, used, free, percent, sin, sout)
|
||||
|
||||
def get_system_cpu_times():
|
||||
"""Return system CPU times as a namedtuple."""
|
||||
user, nice, system, idle = _psutil_osx.get_system_cpu_times()
|
||||
return _cputimes_ntuple(user, nice, system, idle)
|
||||
|
||||
def get_system_per_cpu_times():
|
||||
"""Return system CPU times as a named tuple"""
|
||||
ret = []
|
||||
for cpu_t in _psutil_osx.get_system_per_cpu_times():
|
||||
user, nice, system, idle = cpu_t
|
||||
item = _cputimes_ntuple(user, nice, system, idle)
|
||||
ret.append(item)
|
||||
return ret
|
||||
|
||||
def disk_partitions(all=False):
|
||||
retlist = []
|
||||
partitions = _psutil_osx.get_disk_partitions()
|
||||
for partition in partitions:
|
||||
device, mountpoint, fstype, opts = partition
|
||||
if device == 'none':
|
||||
device = ''
|
||||
if not all:
|
||||
if not os.path.isabs(device) \
|
||||
or not os.path.exists(device):
|
||||
continue
|
||||
ntuple = nt_partition(device, mountpoint, fstype, opts)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
def get_system_users():
|
||||
retlist = []
|
||||
rawlist = _psutil_osx.get_system_users()
|
||||
for item in rawlist:
|
||||
user, tty, hostname, tstamp = item
|
||||
if tty == '~':
|
||||
continue # reboot or shutdown
|
||||
if not tstamp:
|
||||
continue
|
||||
nt = nt_user(user, tty or None, hostname or None, tstamp)
|
||||
retlist.append(nt)
|
||||
return retlist
|
||||
|
||||
|
||||
get_pid_list = _psutil_osx.get_pid_list
|
||||
pid_exists = _psposix.pid_exists
|
||||
get_disk_usage = _psposix.get_disk_usage
|
||||
network_io_counters = _psutil_osx.get_network_io_counters
|
||||
disk_io_counters = _psutil_osx.get_disk_io_counters
|
||||
|
||||
# --- decorator
|
||||
|
||||
def wrap_exceptions(callable):
|
||||
"""Call callable into a try/except clause so that if an
|
||||
OSError EPERM exception is raised we translate it into
|
||||
psutil.AccessDenied.
|
||||
"""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
return callable(self, *args, **kwargs)
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
if err.errno == errno.ESRCH:
|
||||
raise NoSuchProcess(self.pid, self._process_name)
|
||||
if err.errno in (errno.EPERM, errno.EACCES):
|
||||
raise AccessDenied(self.pid, self._process_name)
|
||||
raise
|
||||
return wrapper
|
||||
|
||||
|
||||
_status_map = {
|
||||
_psutil_osx.SIDL : STATUS_IDLE,
|
||||
_psutil_osx.SRUN : STATUS_RUNNING,
|
||||
_psutil_osx.SSLEEP : STATUS_SLEEPING,
|
||||
_psutil_osx.SSTOP : STATUS_STOPPED,
|
||||
_psutil_osx.SZOMB : STATUS_ZOMBIE,
|
||||
}
|
||||
|
||||
class Process(object):
|
||||
"""Wrapper class around underlying C implementation."""
|
||||
|
||||
__slots__ = ["pid", "_process_name"]
|
||||
|
||||
def __init__(self, pid):
|
||||
self.pid = pid
|
||||
self._process_name = None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_name(self):
|
||||
"""Return process name as a string of limited len (15)."""
|
||||
return _psutil_osx.get_process_name(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_exe(self):
|
||||
return _psutil_osx.get_process_exe(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cmdline(self):
|
||||
"""Return process cmdline as a list of arguments."""
|
||||
if not pid_exists(self.pid):
|
||||
raise NoSuchProcess(self.pid, self._process_name)
|
||||
return _psutil_osx.get_process_cmdline(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_ppid(self):
|
||||
"""Return process parent pid."""
|
||||
return _psutil_osx.get_process_ppid(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_cwd(self):
|
||||
return _psutil_osx.get_process_cwd(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_uids(self):
|
||||
real, effective, saved = _psutil_osx.get_process_uids(self.pid)
|
||||
return nt_uids(real, effective, saved)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_gids(self):
|
||||
real, effective, saved = _psutil_osx.get_process_gids(self.pid)
|
||||
return nt_gids(real, effective, saved)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_terminal(self):
|
||||
tty_nr = _psutil_osx.get_process_tty_nr(self.pid)
|
||||
try:
|
||||
return _TERMINAL_MAP[tty_nr]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@wrap_exceptions
|
||||
def get_memory_info(self):
|
||||
"""Return a tuple with the process' RSS and VMS size."""
|
||||
rss, vms = _psutil_osx.get_process_memory_info(self.pid)[:2]
|
||||
return nt_meminfo(rss, vms)
|
||||
|
||||
_nt_ext_mem = namedtuple('meminfo', 'rss vms pfaults pageins')
|
||||
|
||||
@wrap_exceptions
|
||||
def get_ext_memory_info(self):
|
||||
"""Return a tuple with the process' RSS and VMS size."""
|
||||
rss, vms, pfaults, pageins = _psutil_osx.get_process_memory_info(self.pid)
|
||||
return self._nt_ext_mem(rss, vms,
|
||||
pfaults * _PAGESIZE,
|
||||
pageins * _PAGESIZE)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_cpu_times(self):
|
||||
user, system = _psutil_osx.get_process_cpu_times(self.pid)
|
||||
return nt_cputimes(user, system)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_create_time(self):
|
||||
"""Return the start time of the process as a number of seconds since
|
||||
the epoch."""
|
||||
return _psutil_osx.get_process_create_time(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_ctx_switches(self):
|
||||
return nt_ctxsw(*_psutil_osx.get_process_num_ctx_switches(self.pid))
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_num_threads(self):
|
||||
"""Return the number of threads belonging to the process."""
|
||||
return _psutil_osx.get_process_num_threads(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_open_files(self):
|
||||
"""Return files opened by process."""
|
||||
if self.pid == 0:
|
||||
return []
|
||||
files = []
|
||||
rawlist = _psutil_osx.get_process_open_files(self.pid)
|
||||
for path, fd in rawlist:
|
||||
if isfile_strict(path):
|
||||
ntuple = nt_openfile(path, fd)
|
||||
files.append(ntuple)
|
||||
return files
|
||||
|
||||
@wrap_exceptions
|
||||
def get_connections(self, kind='inet'):
|
||||
"""Return etwork connections opened by a process as a list of
|
||||
namedtuples.
|
||||
"""
|
||||
if kind not in conn_tmap:
|
||||
raise ValueError("invalid %r kind argument; choose between %s"
|
||||
% (kind, ', '.join([repr(x) for x in conn_tmap])))
|
||||
families, types = conn_tmap[kind]
|
||||
ret = _psutil_osx.get_process_connections(self.pid, families, types)
|
||||
return [nt_connection(*conn) for conn in ret]
|
||||
|
||||
@wrap_exceptions
|
||||
def get_num_fds(self):
|
||||
if self.pid == 0:
|
||||
return 0
|
||||
return _psutil_osx.get_process_num_fds(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def process_wait(self, timeout=None):
|
||||
try:
|
||||
return _psposix.wait_pid(self.pid, timeout)
|
||||
except TimeoutExpired:
|
||||
raise TimeoutExpired(self.pid, self._process_name)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_nice(self):
|
||||
return _psutil_posix.getpriority(self.pid)
|
||||
|
||||
@wrap_exceptions
|
||||
def set_process_nice(self, value):
|
||||
return _psutil_posix.setpriority(self.pid, value)
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_status(self):
|
||||
code = _psutil_osx.get_process_status(self.pid)
|
||||
if code in _status_map:
|
||||
return _status_map[code]
|
||||
return constant(-1, "?")
|
||||
|
||||
@wrap_exceptions
|
||||
def get_process_threads(self):
|
||||
"""Return the number of threads belonging to the process."""
|
||||
rawlist = _psutil_osx.get_process_threads(self.pid)
|
||||
retlist = []
|
||||
for thread_id, utime, stime in rawlist:
|
||||
ntuple = nt_thread(thread_id, utime, stime)
|
||||
retlist.append(ntuple)
|
||||
return retlist
|
||||
|
||||
nt_mmap_grouped = namedtuple('mmap',
|
||||
'path rss private swapped dirtied ref_count shadow_depth')
|
||||
nt_mmap_ext = namedtuple('mmap',
|
||||
'addr perms path rss private swapped dirtied ref_count shadow_depth')
|
||||
|
||||
@wrap_exceptions
|
||||
def get_memory_maps(self):
|
||||
return _psutil_osx.get_process_memory_maps(self.pid)
|
118
vendor/psutil/_psposix.py
vendored
Normal file
118
vendor/psutil/_psposix.py
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: _psposix.py 1409 2012-07-04 08:21:06Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Routines common to all posix systems."""
|
||||
|
||||
import os
|
||||
import errno
|
||||
import psutil
|
||||
import sys
|
||||
import time
|
||||
import glob
|
||||
|
||||
from psutil.error import TimeoutExpired
|
||||
from psutil._common import nt_diskinfo, usage_percent
|
||||
|
||||
|
||||
def pid_exists(pid):
|
||||
"""Check whether pid exists in the current process table."""
|
||||
if not isinstance(pid, int):
|
||||
raise TypeError('an integer is required')
|
||||
if pid < 0:
|
||||
return False
|
||||
try:
|
||||
os.kill(pid, 0)
|
||||
except OSError:
|
||||
e = sys.exc_info()[1]
|
||||
return e.errno == errno.EPERM
|
||||
else:
|
||||
return True
|
||||
|
||||
def wait_pid(pid, timeout=None):
|
||||
"""Wait for process with pid 'pid' to terminate and return its
|
||||
exit status code as an integer.
|
||||
|
||||
If pid is not a children of os.getpid() (current process) just
|
||||
waits until the process disappears and return None.
|
||||
|
||||
If pid does not exist at all return None immediately.
|
||||
|
||||
Raise TimeoutExpired on timeout expired.
|
||||
"""
|
||||
def check_timeout(delay):
|
||||
if timeout is not None:
|
||||
if time.time() >= stop_at:
|
||||
raise TimeoutExpired(pid)
|
||||
time.sleep(delay)
|
||||
return min(delay * 2, 0.04)
|
||||
|
||||
if timeout is not None:
|
||||
waitcall = lambda: os.waitpid(pid, os.WNOHANG)
|
||||
stop_at = time.time() + timeout
|
||||
else:
|
||||
waitcall = lambda: os.waitpid(pid, 0)
|
||||
|
||||
delay = 0.0001
|
||||
while 1:
|
||||
try:
|
||||
retpid, status = waitcall()
|
||||
except OSError:
|
||||
err = sys.exc_info()[1]
|
||||
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 1:
|
||||
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 get_disk_usage(path):
|
||||
"""Return disk usage associated with path."""
|
||||
st = os.statvfs(path)
|
||||
free = (st.f_bavail * st.f_frsize)
|
||||
total = (st.f_blocks * st.f_frsize)
|
||||
used = (st.f_blocks - st.f_bfree) * st.f_frsize
|
||||
percent = usage_percent(used, total, _round=1)
|
||||
# NB: the percentage is -5% than what shown by df due to
|
||||
# reserved blocks that we are currently not considering:
|
||||
# http://goo.gl/sWGbH
|
||||
return nt_diskinfo(total, used, free, percent)
|
||||
|
||||
def _get_terminal_map():
|
||||
ret = {}
|
||||
ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
|
||||
for name in ls:
|
||||
assert name not in ret
|
||||
ret[os.stat(name).st_rdev] = name
|
||||
return ret
|
1777
vendor/psutil/_psutil_bsd.c
vendored
Normal file
1777
vendor/psutil/_psutil_bsd.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
52
vendor/psutil/_psutil_bsd.h
vendored
Normal file
52
vendor/psutil/_psutil_bsd.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* $Id: _psutil_bsd.h 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* BSD platform-specific module methods for _psutil_bsd
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
// --- per-process functions
|
||||
|
||||
static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_name(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_exe(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_ppid(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_uids(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_gids(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_connections(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_create_time(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_fds(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_status(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_tty_nr(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_ctx_switches(PyObject* self, PyObject* args);
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
|
||||
static PyObject* get_process_open_files(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cwd(PyObject* self, PyObject* args);
|
||||
#endif
|
||||
|
||||
// --- system-related functions
|
||||
|
||||
static PyObject* get_pid_list(PyObject* self, PyObject* args);
|
||||
static PyObject* get_num_cpus(PyObject* self, PyObject* args);
|
||||
static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
|
||||
static PyObject* get_swap_mem(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
|
||||
static PyObject* get_system_per_cpu_times(PyObject* self, PyObject* args);
|
||||
#endif
|
||||
static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
|
||||
static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_users(PyObject* self, PyObject* args);
|
39
vendor/psutil/_psutil_common.c
vendored
Normal file
39
vendor/psutil/_psutil_common.c
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* $Id: _psutil_common.c 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Routines common to all platforms.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
|
||||
/*
|
||||
* Set OSError(errno=ESRCH, strerror="No such process") Python exception.
|
||||
*/
|
||||
PyObject *
|
||||
NoSuchProcess(void) {
|
||||
PyObject *exc;
|
||||
char *msg = strerror(ESRCH);
|
||||
exc = PyObject_CallFunction(PyExc_OSError, "(is)", ESRCH, msg);
|
||||
PyErr_SetObject(PyExc_OSError, exc);
|
||||
Py_XDECREF(exc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set OSError(errno=EACCES, strerror="Permission denied") Python exception.
|
||||
*/
|
||||
PyObject *
|
||||
AccessDenied(void) {
|
||||
PyObject *exc;
|
||||
char *msg = strerror(EACCES);
|
||||
exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg);
|
||||
PyErr_SetObject(PyExc_OSError, exc);
|
||||
Py_XDECREF(exc);
|
||||
return NULL;
|
||||
}
|
||||
|
13
vendor/psutil/_psutil_common.h
vendored
Normal file
13
vendor/psutil/_psutil_common.h
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* $Id: _psutil_common.h 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
PyObject* NoSuchProcess(void);
|
||||
PyObject* AccessDenied(void);
|
||||
|
338
vendor/psutil/_psutil_linux.c
vendored
Normal file
338
vendor/psutil/_psutil_linux.c
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* $Id: _psutil_linux.c 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Linux-specific functions.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <mntent.h>
|
||||
#include <utmp.h>
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include "_psutil_linux.h"
|
||||
|
||||
|
||||
#define HAS_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
|
||||
|
||||
#if HAS_IOPRIO
|
||||
enum {
|
||||
IOPRIO_WHO_PROCESS = 1,
|
||||
};
|
||||
|
||||
static inline int
|
||||
ioprio_get(int which, int who)
|
||||
{
|
||||
return syscall(__NR_ioprio_get, which, who);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ioprio_set(int which, int who, int ioprio)
|
||||
{
|
||||
return syscall(__NR_ioprio_set, which, who, ioprio);
|
||||
}
|
||||
|
||||
#define IOPRIO_CLASS_SHIFT 13
|
||||
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
|
||||
|
||||
#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
|
||||
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
|
||||
#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
|
||||
|
||||
|
||||
/*
|
||||
* Return a (ioclass, iodata) Python tuple representing process I/O priority.
|
||||
*/
|
||||
static PyObject*
|
||||
linux_ioprio_get(PyObject* self, PyObject* args)
|
||||
{
|
||||
long pid;
|
||||
int ioprio, ioclass, iodata;
|
||||
if (! PyArg_ParseTuple(args, "l", &pid)) {
|
||||
return NULL;
|
||||
}
|
||||
ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
|
||||
if (ioprio == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
ioclass = IOPRIO_PRIO_CLASS(ioprio);
|
||||
iodata = IOPRIO_PRIO_DATA(ioprio);
|
||||
return Py_BuildValue("ii", ioclass, iodata);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A wrapper around ioprio_set(); sets process I/O priority.
|
||||
* ioclass can be either IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE
|
||||
* or 0. iodata goes from 0 to 7 depending on ioclass specified.
|
||||
*/
|
||||
static PyObject*
|
||||
linux_ioprio_set(PyObject* self, PyObject* args)
|
||||
{
|
||||
long pid;
|
||||
int ioprio, ioclass, iodata;
|
||||
int retval;
|
||||
|
||||
if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata)) {
|
||||
return NULL;
|
||||
}
|
||||
ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata);
|
||||
retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio);
|
||||
if (retval == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Return disk mounted partitions as a list of tuples including device,
|
||||
* mount point and filesystem type
|
||||
*/
|
||||
static PyObject*
|
||||
get_disk_partitions(PyObject* self, PyObject* args)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
struct mntent *entry;
|
||||
PyObject* py_retlist = PyList_New(0);
|
||||
PyObject* py_tuple = 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_SetFromErrno(PyExc_OSError);
|
||||
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*
|
||||
get_sysinfo(PyObject* self, PyObject* args)
|
||||
{
|
||||
struct sysinfo info;
|
||||
if (sysinfo(&info) != 0) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
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
|
||||
// TODO: we can also determine BOOT_TIME here
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return process CPU affinity as a Python long (the bitmask)
|
||||
*/
|
||||
static PyObject*
|
||||
get_process_cpu_affinity(PyObject* self, PyObject* args)
|
||||
{
|
||||
unsigned long mask;
|
||||
unsigned int len = sizeof(mask);
|
||||
long pid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &pid)) {
|
||||
return NULL;
|
||||
}
|
||||
if (sched_getaffinity(pid, len, (cpu_set_t *)&mask) < 0) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return Py_BuildValue("l", mask);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set process CPU affinity; expects a bitmask
|
||||
*/
|
||||
static PyObject*
|
||||
set_process_cpu_affinity(PyObject* self, PyObject* args)
|
||||
{
|
||||
unsigned long mask;
|
||||
unsigned int len = sizeof(mask);
|
||||
long pid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ll", &pid, &mask)) {
|
||||
return NULL;
|
||||
}
|
||||
if (sched_setaffinity(pid, len, (cpu_set_t *)&mask)) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return currently connected users as a list of tuples.
|
||||
*/
|
||||
static PyObject*
|
||||
get_system_users(PyObject* self, PyObject* args)
|
||||
{
|
||||
PyObject *ret_list = PyList_New(0);
|
||||
PyObject *tuple = NULL;
|
||||
PyObject *user_proc = NULL;
|
||||
struct utmp *ut;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Define the psutil C module methods and initialize the module.
|
||||
*/
|
||||
static PyMethodDef
|
||||
PsutilMethods[] =
|
||||
{
|
||||
#if HAS_IOPRIO
|
||||
{"ioprio_get", linux_ioprio_get, METH_VARARGS,
|
||||
"Get process I/O priority"},
|
||||
{"ioprio_set", linux_ioprio_set, METH_VARARGS,
|
||||
"Set process I/O priority"},
|
||||
#endif
|
||||
{"get_disk_partitions", get_disk_partitions, METH_VARARGS,
|
||||
"Return disk mounted partitions as a list of tuples including "
|
||||
"device, mount point and filesystem type"},
|
||||
{"get_sysinfo", get_sysinfo, METH_VARARGS,
|
||||
"A wrapper around sysinfo(), return system memory usage statistics"},
|
||||
{"get_process_cpu_affinity", get_process_cpu_affinity, METH_VARARGS,
|
||||
"Return process CPU affinity as a Python long (the bitmask)."},
|
||||
{"set_process_cpu_affinity", set_process_cpu_affinity, METH_VARARGS,
|
||||
"Set process CPU affinity; expects a bitmask."},
|
||||
{"get_system_users", get_system_users, METH_VARARGS,
|
||||
"Return currently connected users as a list of tuples"},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
struct module_state {
|
||||
PyObject *error;
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
|
||||
#else
|
||||
#define GETSTATE(m) (&_state)
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
||||
static int
|
||||
psutil_linux_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psutil_linux_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct PyModuleDef
|
||||
moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"psutil_linux",
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
PsutilMethods,
|
||||
NULL,
|
||||
psutil_linux_traverse,
|
||||
psutil_linux_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyObject *
|
||||
PyInit__psutil_linux(void)
|
||||
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
void init_psutil_linux(void)
|
||||
#endif
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods);
|
||||
#endif
|
||||
if (module == NULL) {
|
||||
INITERROR;
|
||||
}
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return module;
|
||||
#endif
|
||||
}
|
19
vendor/psutil/_psutil_linux.h
vendored
Normal file
19
vendor/psutil/_psutil_linux.h
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* $Id: _psutil_linux.h 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* LINUX specific module methods for _psutil_linux
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject* linux_ioprio_get(PyObject* self, PyObject* args);
|
||||
static PyObject* linux_ioprio_set(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
|
||||
static PyObject* get_sysinfo(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cpu_affinity(PyObject* self, PyObject* args);
|
||||
static PyObject* set_process_cpu_affinity(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_users(PyObject* self, PyObject* args);
|
2904
vendor/psutil/_psutil_mswindows.c
vendored
Normal file
2904
vendor/psutil/_psutil_mswindows.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
69
vendor/psutil/_psutil_mswindows.h
vendored
Normal file
69
vendor/psutil/_psutil_mswindows.h
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* $Id: _psutil_mswindows.h 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Windows platform-specific module methods for _psutil_mswindows
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <windows.h>
|
||||
|
||||
// --- per-process functions
|
||||
|
||||
static PyObject* get_process_name(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_exe(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_ppid(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_create_time(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cwd(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_open_files(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_username(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_connections(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_priority(PyObject* self, PyObject* args);
|
||||
static PyObject* set_process_priority(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cpu_affinity(PyObject* self, PyObject* args);
|
||||
static PyObject* set_process_cpu_affinity(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_handles(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_ctx_switches(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
|
||||
|
||||
static PyObject* get_process_cpu_times_2(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_create_time_2(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_handles_2(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_io_counters_2(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_info_2(PyObject* self, PyObject* args);
|
||||
|
||||
static PyObject* suspend_process(PyObject* self, PyObject* args);
|
||||
static PyObject* resume_process(PyObject* self, PyObject* args);
|
||||
static PyObject* is_process_suspended(PyObject* self, PyObject* args);
|
||||
static PyObject* process_wait(PyObject* self, PyObject* args);
|
||||
static PyObject* kill_process(PyObject* self, PyObject* args);
|
||||
|
||||
// --- system-related functions
|
||||
|
||||
static PyObject* get_pid_list(PyObject* self, PyObject* args);
|
||||
static PyObject* get_num_cpus(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_uptime(PyObject* self, PyObject* args);
|
||||
static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* pid_exists(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_usage(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
|
||||
static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_users(PyObject* self, PyObject* args);
|
||||
|
||||
// --- windows API bindings
|
||||
|
||||
static PyObject* win32_QueryDosDevice(PyObject* self, PyObject* args);
|
||||
|
||||
// --- internal
|
||||
int suspend_resume_process(DWORD pid, int suspend);
|
1792
vendor/psutil/_psutil_osx.c
vendored
Normal file
1792
vendor/psutil/_psutil_osx.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
44
vendor/psutil/_psutil_osx.h
vendored
Normal file
44
vendor/psutil/_psutil_osx.h
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* $Id: _psutil_osx.h 1498 2012-07-24 21:41:28Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* OS X platform-specific module methods for _psutil_osx
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
// --- per-process functions
|
||||
static PyObject* get_process_name(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cwd(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_exe(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_ppid(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_uids(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_gids(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_create_time(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_status(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_threads(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_open_files(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_connections(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_num_fds(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_tty_nr(PyObject* self, PyObject* args);
|
||||
static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
|
||||
|
||||
// --- system-related functions
|
||||
static PyObject* get_pid_list(PyObject* self, PyObject* args);
|
||||
static PyObject* get_num_cpus(PyObject* self, PyObject* args);
|
||||
static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
|
||||
static PyObject* get_swap_mem(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_per_cpu_times(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
|
||||
static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
|
||||
static PyObject* get_system_users(PyObject* self, PyObject* args);
|
134
vendor/psutil/_psutil_posix.c
vendored
Normal file
134
vendor/psutil/_psutil_posix.c
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* $Id: _psutil_posix.c 1223 2011-11-09 23:47:55Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Functions specific to all POSIX compliant platforms.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "_psutil_posix.h"
|
||||
|
||||
|
||||
/*
|
||||
* Given a PID return process priority as a Python integer.
|
||||
*/
|
||||
static PyObject*
|
||||
posix_getpriority(PyObject* self, PyObject* args)
|
||||
{
|
||||
long pid;
|
||||
int priority;
|
||||
errno = 0;
|
||||
if (! PyArg_ParseTuple(args, "l", &pid)) {
|
||||
return NULL;
|
||||
}
|
||||
priority = getpriority(PRIO_PROCESS, pid);
|
||||
if (errno != 0) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return Py_BuildValue("i", priority);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a PID and a value change process priority.
|
||||
*/
|
||||
static PyObject*
|
||||
posix_setpriority(PyObject* self, PyObject* args)
|
||||
{
|
||||
long pid;
|
||||
int priority;
|
||||
int retval;
|
||||
if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
|
||||
return NULL;
|
||||
}
|
||||
retval = setpriority(PRIO_PROCESS, pid, priority);
|
||||
if (retval == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* define the psutil C module methods and initialize the module.
|
||||
*/
|
||||
static PyMethodDef
|
||||
PsutilMethods[] =
|
||||
{
|
||||
{"getpriority", posix_getpriority, METH_VARARGS,
|
||||
"Return process priority"},
|
||||
{"setpriority", posix_setpriority, METH_VARARGS,
|
||||
"Set process priority"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
struct module_state {
|
||||
PyObject *error;
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
|
||||
#else
|
||||
#define GETSTATE(m) (&_state)
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
||||
static int
|
||||
psutil_posix_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psutil_posix_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct PyModuleDef
|
||||
moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"psutil_posix",
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
PsutilMethods,
|
||||
NULL,
|
||||
psutil_posix_traverse,
|
||||
psutil_posix_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyObject *
|
||||
PyInit__psutil_posix(void)
|
||||
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
void init_psutil_posix(void)
|
||||
#endif
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods);
|
||||
#endif
|
||||
if (module == NULL) {
|
||||
INITERROR;
|
||||
}
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
14
vendor/psutil/_psutil_posix.h
vendored
Normal file
14
vendor/psutil/_psutil_posix.h
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* $Id: _psutil_posix.h 1223 2011-11-09 23:47:55Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* POSIX specific module methods for _psutil_posix
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject* posix_getpriority(PyObject* self, PyObject* args);
|
||||
static PyObject* posix_setpriority(PyObject* self, PyObject* args);
|
271
vendor/psutil/arch/bsd/process_info.c
vendored
Normal file
271
vendor/psutil/arch/bsd/process_info.c
vendored
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* $Id: process_info.c 1462 2012-07-18 03:12:08Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Helper functions related to fetching process information. Used by _psutil_bsd
|
||||
* module methods.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/proc.h>
|
||||
#include <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
|
||||
get_proc_list(struct kinfo_proc **procList, size_t *procCount)
|
||||
{
|
||||
int err;
|
||||
struct kinfo_proc * result;
|
||||
int done;
|
||||
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
|
||||
// Declaring name as const requires us to cast it when passing it to
|
||||
// sysctl because the prototype doesn't include the const modifier.
|
||||
size_t length;
|
||||
|
||||
assert( procList != NULL);
|
||||
assert(*procList == NULL);
|
||||
assert(procCount != NULL);
|
||||
|
||||
*procCount = 0;
|
||||
|
||||
/*
|
||||
* We start by calling sysctl with result == NULL and length == 0.
|
||||
* That will succeed, and set length to the appropriate length.
|
||||
* We then allocate a buffer of that size and call sysctl again
|
||||
* with that buffer. If that succeeds, we're done. If that fails
|
||||
* with ENOMEM, we have to throw away our buffer and loop. Note
|
||||
* that the loop causes use to call sysctl with NULL again; this
|
||||
* is necessary because the ENOMEM failure case sets length to
|
||||
* the amount of data returned, not the amount of data that
|
||||
* could have been returned.
|
||||
*/
|
||||
result = NULL;
|
||||
done = 0;
|
||||
do {
|
||||
assert(result == NULL);
|
||||
// Call sysctl with a NULL buffer.
|
||||
length = 0;
|
||||
err = sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1,
|
||||
NULL, &length, NULL, 0);
|
||||
if (err == -1)
|
||||
err = errno;
|
||||
|
||||
// Allocate an appropriately sized buffer based on the results
|
||||
// from the previous call.
|
||||
if (err == 0) {
|
||||
result = malloc(length);
|
||||
if (result == NULL)
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
// Call sysctl again with the new buffer. If we get an ENOMEM
|
||||
// error, toss away our buffer and start again.
|
||||
if (err == 0) {
|
||||
err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
|
||||
result, &length, NULL, 0);
|
||||
if (err == -1)
|
||||
err = errno;
|
||||
if (err == 0) {
|
||||
done = 1;
|
||||
}
|
||||
else if (err == ENOMEM) {
|
||||
assert(result != NULL);
|
||||
free(result);
|
||||
result = NULL;
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
} while (err == 0 && ! done);
|
||||
|
||||
// Clean up and establish post conditions.
|
||||
if (err != 0 && result != NULL) {
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
*procList = result;
|
||||
*procCount = length / sizeof(struct kinfo_proc);
|
||||
|
||||
assert((err == 0) == (*procList != NULL));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
*getcmdpath(long pid, size_t *pathsize)
|
||||
{
|
||||
int mib[4];
|
||||
char *path;
|
||||
size_t size = 0;
|
||||
|
||||
/*
|
||||
* Make a sysctl() call to get the raw argument space of the process.
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = pid;
|
||||
|
||||
// call with a null buffer first to determine if we need a buffer
|
||||
if (sysctl(mib, 4, NULL, &size, NULL, 0) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = malloc(size);
|
||||
if (path == NULL) {
|
||||
PyErr_SetString(PyExc_MemoryError, "couldn't allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*pathsize = size;
|
||||
if (sysctl(mib, 4, path, &size, NULL, 0) == -1) {
|
||||
free(path);
|
||||
return NULL; /* Insufficient privileges */
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Borrowed from psi Python System Information project
|
||||
*
|
||||
* Get command arguments and environment variables.
|
||||
*
|
||||
* Based on code from ps.
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success;
|
||||
* -1 for failure (Exception raised);
|
||||
* 1 for insufficient privileges.
|
||||
*/
|
||||
char
|
||||
*getcmdargs(long pid, size_t *argsize)
|
||||
{
|
||||
int mib[4];
|
||||
size_t size, argmax;
|
||||
char *procargs = NULL;
|
||||
|
||||
/* Get the maximum process arguments size. */
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_ARGMAX;
|
||||
|
||||
size = sizeof(argmax);
|
||||
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
|
||||
return NULL;
|
||||
|
||||
/* Allocate space for the arguments. */
|
||||
procargs = (char *)malloc(argmax);
|
||||
if (procargs == NULL) {
|
||||
PyErr_SetString(PyExc_MemoryError, "couldn't allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a sysctl() call to get the raw argument space of the process.
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_ARGS;
|
||||
mib[3] = pid;
|
||||
|
||||
size = argmax;
|
||||
if (sysctl(mib, 4, procargs, &size, NULL, 0) == -1) {
|
||||
free(procargs);
|
||||
return NULL; /* Insufficient privileges */
|
||||
}
|
||||
|
||||
// return string and set the length of arguments
|
||||
*argsize = size;
|
||||
return procargs;
|
||||
}
|
||||
|
||||
|
||||
/* returns the command line as a python list object */
|
||||
PyObject*
|
||||
get_arg_list(long pid)
|
||||
{
|
||||
char *argstr = NULL;
|
||||
int pos = 0;
|
||||
size_t argsize = 0;
|
||||
PyObject *retlist = Py_BuildValue("[]");
|
||||
PyObject *item = NULL;
|
||||
|
||||
if (pid < 0) {
|
||||
return retlist;
|
||||
}
|
||||
|
||||
argstr = getcmdargs(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
|
||||
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;
|
||||
}
|
21
vendor/psutil/arch/bsd/process_info.h
vendored
Normal file
21
vendor/psutil/arch/bsd/process_info.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* $Id: process_info.h 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Helper functions related to fetching process information. Used by _psutil_bsd
|
||||
* module methods.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
typedef struct kinfo_proc kinfo_proc;
|
||||
|
||||
int get_proc_list(struct kinfo_proc **procList, size_t *procCount);
|
||||
char *getcmdargs(long pid, size_t *argsize);
|
||||
char *getcmdpath(long pid, size_t *pathsize);
|
||||
PyObject* get_arg_list(long pid);
|
||||
int pid_exists(long pid);
|
||||
|
232
vendor/psutil/arch/mswindows/ntextapi.h
vendored
Normal file
232
vendor/psutil/arch/mswindows/ntextapi.h
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* $Id: ntextapi.h 1452 2012-07-13 19:02:07Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum _KTHREAD_STATE
|
||||
{
|
||||
Initialized,
|
||||
Ready,
|
||||
Running,
|
||||
Standby,
|
||||
Terminated,
|
||||
Waiting,
|
||||
Transition,
|
||||
DeferredReady,
|
||||
GateWait,
|
||||
MaximumThreadState
|
||||
} KTHREAD_STATE, *PKTHREAD_STATE;
|
||||
|
||||
typedef enum _KWAIT_REASON
|
||||
{
|
||||
Executive = 0,
|
||||
FreePage = 1,
|
||||
PageIn = 2,
|
||||
PoolAllocation = 3,
|
||||
DelayExecution = 4,
|
||||
Suspended = 5,
|
||||
UserRequest = 6,
|
||||
WrExecutive = 7,
|
||||
WrFreePage = 8,
|
||||
WrPageIn = 9,
|
||||
WrPoolAllocation = 10,
|
||||
WrDelayExecution = 11,
|
||||
WrSuspended = 12,
|
||||
WrUserRequest = 13,
|
||||
WrEventPair = 14,
|
||||
WrQueue = 15,
|
||||
WrLpcReceive = 16,
|
||||
WrLpcReply = 17,
|
||||
WrVirtualMemory = 18,
|
||||
WrPageOut = 19,
|
||||
WrRendezvous = 20,
|
||||
Spare2 = 21,
|
||||
Spare3 = 22,
|
||||
Spare4 = 23,
|
||||
Spare5 = 24,
|
||||
WrCalloutStack = 25,
|
||||
WrKernel = 26,
|
||||
WrResource = 27,
|
||||
WrPushLock = 28,
|
||||
WrMutex = 29,
|
||||
WrQuantumEnd = 30,
|
||||
WrDispatchInt = 31,
|
||||
WrPreempted = 32,
|
||||
WrYieldExecution = 33,
|
||||
WrFastMutex = 34,
|
||||
WrGuardedMutex = 35,
|
||||
WrRundown = 36,
|
||||
MaximumWaitReason = 37
|
||||
} KWAIT_REASON, *PKWAIT_REASON;
|
||||
|
||||
|
||||
typedef struct _CLIENT_ID
|
||||
{
|
||||
HANDLE UniqueProcess;
|
||||
HANDLE UniqueThread;
|
||||
} CLIENT_ID, *PCLIENT_ID;
|
||||
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
|
||||
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER BootTime;
|
||||
LARGE_INTEGER CurrentTime;
|
||||
LARGE_INTEGER TimeZoneBias;
|
||||
ULONG TimeZoneId;
|
||||
ULONG Reserved;
|
||||
ULONGLONG BootTimeBias;
|
||||
ULONGLONG SleepTimeBias;
|
||||
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_THREAD_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER CreateTime;
|
||||
ULONG WaitTime;
|
||||
PVOID StartAddress;
|
||||
CLIENT_ID ClientId;
|
||||
LONG Priority;
|
||||
LONG BasePriority;
|
||||
ULONG ContextSwitches;
|
||||
ULONG ThreadState;
|
||||
KWAIT_REASON WaitReason;
|
||||
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
|
||||
|
||||
typedef struct _TEB *PTEB;
|
||||
|
||||
// private
|
||||
typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION
|
||||
{
|
||||
SYSTEM_THREAD_INFORMATION ThreadInfo;
|
||||
PVOID StackBase;
|
||||
PVOID StackLimit;
|
||||
PVOID Win32StartAddress;
|
||||
PTEB TebBase;
|
||||
ULONG_PTR Reserved2;
|
||||
ULONG_PTR Reserved3;
|
||||
ULONG_PTR Reserved4;
|
||||
} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PROCESS_INFORMATION
|
||||
{
|
||||
ULONG NextEntryOffset;
|
||||
ULONG NumberOfThreads;
|
||||
LARGE_INTEGER SpareLi1;
|
||||
LARGE_INTEGER SpareLi2;
|
||||
LARGE_INTEGER SpareLi3;
|
||||
LARGE_INTEGER CreateTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
UNICODE_STRING ImageName;
|
||||
LONG BasePriority;
|
||||
HANDLE UniqueProcessId;
|
||||
HANDLE InheritedFromUniqueProcessId;
|
||||
ULONG HandleCount;
|
||||
ULONG SessionId;
|
||||
ULONG_PTR PageDirectoryBase;
|
||||
SIZE_T PeakVirtualSize;
|
||||
SIZE_T VirtualSize;
|
||||
DWORD PageFaultCount;
|
||||
SIZE_T PeakWorkingSetSize;
|
||||
SIZE_T WorkingSetSize;
|
||||
SIZE_T QuotaPeakPagedPoolUsage;
|
||||
SIZE_T QuotaPagedPoolUsage;
|
||||
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
SIZE_T QuotaNonPagedPoolUsage;
|
||||
SIZE_T PagefileUsage;
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivatePageCount;
|
||||
LARGE_INTEGER ReadOperationCount;
|
||||
LARGE_INTEGER WriteOperationCount;
|
||||
LARGE_INTEGER OtherOperationCount;
|
||||
LARGE_INTEGER ReadTransferCount;
|
||||
LARGE_INTEGER WriteTransferCount;
|
||||
LARGE_INTEGER OtherTransferCount;
|
||||
SYSTEM_THREAD_INFORMATION Threads[1];
|
||||
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
|
||||
|
||||
|
||||
// structures and enums from winternl.h (not available under mingw)
|
||||
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
LARGE_INTEGER IdleTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER Reserved1[2];
|
||||
ULONG Reserved2;
|
||||
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
||||
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation = 0,
|
||||
SystemPerformanceInformation = 2,
|
||||
SystemTimeOfDayInformation = 3,
|
||||
SystemProcessInformation = 5,
|
||||
SystemProcessorPerformanceInformation = 8,
|
||||
SystemInterruptInformation = 23,
|
||||
SystemExceptionInformation = 33,
|
||||
SystemRegistryQuotaInformation = 37,
|
||||
SystemLookasideInformation = 45
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
|
||||
// ================================================
|
||||
// get_system_users support ()
|
||||
// ================================================
|
||||
|
||||
typedef struct _WINSTATION_INFO {
|
||||
BYTE Reserved1[72];
|
||||
ULONG SessionId;
|
||||
BYTE Reserved2[4];
|
||||
FILETIME ConnectTime;
|
||||
FILETIME DisconnectTime;
|
||||
FILETIME LastInputTime;
|
||||
FILETIME LoginTime;
|
||||
BYTE Reserved3[1096];
|
||||
FILETIME CurrentTime;
|
||||
} WINSTATION_INFO, *PWINSTATION_INFO;
|
||||
|
||||
typedef enum _WINSTATIONINFOCLASS {
|
||||
WinStationInformation = 8
|
||||
} WINSTATIONINFOCLASS;
|
||||
|
||||
typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
|
||||
(HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
|
||||
|
||||
typedef struct _WINSTATIONINFORMATIONW {
|
||||
BYTE Reserved2[70];
|
||||
ULONG LogonId;
|
||||
BYTE Reserved3[1140];
|
||||
} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
|
||||
|
||||
// start mingw support:
|
||||
// http://www.koders.com/c/fid7C02CAE627C526914CDEB427405B51DF393A5EFA.aspx
|
||||
#ifndef _INC_WTSAPI
|
||||
typedef struct _WTS_CLIENT_ADDRESS {
|
||||
DWORD AddressFamily; // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
|
||||
BYTE Address[20]; // client network address
|
||||
} WTS_CLIENT_ADDRESS, * PWTS_CLIENT_ADDRESS;
|
||||
|
||||
HANDLE
|
||||
WINAPI
|
||||
WTSOpenServerA(
|
||||
IN LPSTR pServerName
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
WTSCloseServer(
|
||||
IN HANDLE hServer
|
||||
);
|
||||
#endif
|
322
vendor/psutil/arch/mswindows/process_handles.c
vendored
Normal file
322
vendor/psutil/arch/mswindows/process_handles.c
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* $Id: process_handles.c 1463 2012-07-18 13:06:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "process_handles.h"
|
||||
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(x) ((x) >= 0)
|
||||
#endif
|
||||
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
|
||||
|
||||
#define SystemHandleInformation 16
|
||||
#define ObjectBasicInformation 0
|
||||
#define ObjectNameInformation 1
|
||||
#define ObjectTypeInformation 2
|
||||
|
||||
|
||||
typedef LONG NTSTATUS;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
|
||||
ULONG SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
|
||||
HANDLE SourceProcessHandle,
|
||||
HANDLE SourceHandle,
|
||||
HANDLE TargetProcessHandle,
|
||||
PHANDLE TargetHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
ULONG Attributes,
|
||||
ULONG Options
|
||||
);
|
||||
|
||||
typedef NTSTATUS (NTAPI *_NtQueryObject)(
|
||||
HANDLE ObjectHandle,
|
||||
ULONG ObjectInformationClass,
|
||||
PVOID ObjectInformation,
|
||||
ULONG ObjectInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
typedef struct _SYSTEM_HANDLE
|
||||
{
|
||||
ULONG ProcessId;
|
||||
BYTE ObjectTypeNumber;
|
||||
BYTE Flags;
|
||||
USHORT Handle;
|
||||
PVOID Object;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION
|
||||
{
|
||||
ULONG HandleCount;
|
||||
SYSTEM_HANDLE Handles[1];
|
||||
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
|
||||
|
||||
typedef enum _POOL_TYPE
|
||||
{
|
||||
NonPagedPool,
|
||||
PagedPool,
|
||||
NonPagedPoolMustSucceed,
|
||||
DontUseThisType,
|
||||
NonPagedPoolCacheAligned,
|
||||
PagedPoolCacheAligned,
|
||||
NonPagedPoolCacheAlignedMustS
|
||||
} POOL_TYPE, *PPOOL_TYPE;
|
||||
|
||||
typedef struct _OBJECT_TYPE_INFORMATION
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
ULONG TotalPagedPoolUsage;
|
||||
ULONG TotalNonPagedPoolUsage;
|
||||
ULONG TotalNamePoolUsage;
|
||||
ULONG TotalHandleTableUsage;
|
||||
ULONG HighWaterNumberOfObjects;
|
||||
ULONG HighWaterNumberOfHandles;
|
||||
ULONG HighWaterPagedPoolUsage;
|
||||
ULONG HighWaterNonPagedPoolUsage;
|
||||
ULONG HighWaterNamePoolUsage;
|
||||
ULONG HighWaterHandleTableUsage;
|
||||
ULONG InvalidAttributes;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
ULONG ValidAccess;
|
||||
BOOLEAN SecurityRequired;
|
||||
BOOLEAN MaintainHandleCount;
|
||||
USHORT MaintainTypeList;
|
||||
POOL_TYPE PoolType;
|
||||
ULONG PagedPoolUsage;
|
||||
ULONG NonPagedPoolUsage;
|
||||
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
||||
|
||||
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
|
||||
{
|
||||
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
|
||||
}
|
||||
|
||||
|
||||
PyObject*
|
||||
get_open_files(long pid, HANDLE processHandle)
|
||||
{
|
||||
_NtQuerySystemInformation NtQuerySystemInformation =
|
||||
GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
|
||||
_NtDuplicateObject NtDuplicateObject =
|
||||
GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
|
||||
_NtQueryObject NtQueryObject =
|
||||
GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
|
||||
|
||||
NTSTATUS status;
|
||||
PSYSTEM_HANDLE_INFORMATION handleInfo;
|
||||
ULONG handleInfoSize = 0x10000;
|
||||
|
||||
ULONG i;
|
||||
ULONG fileNameLength;
|
||||
PyObject *filesList = Py_BuildValue("[]");
|
||||
PyObject *arg = NULL;
|
||||
PyObject *fileFromWchar = NULL;
|
||||
|
||||
|
||||
|
||||
handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
|
||||
|
||||
/* NtQuerySystemInformation won't give us the correct buffer size,
|
||||
so we guess by doubling the buffer size. */
|
||||
while ((status = NtQuerySystemInformation(
|
||||
SystemHandleInformation,
|
||||
handleInfo,
|
||||
handleInfoSize,
|
||||
NULL
|
||||
)) == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
|
||||
}
|
||||
|
||||
/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
|
||||
if (!NT_SUCCESS(status)) {
|
||||
//printf("NtQuerySystemInformation failed!\n");
|
||||
Py_DECREF(filesList);
|
||||
free(handleInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < handleInfo->HandleCount; i++)
|
||||
{
|
||||
SYSTEM_HANDLE handle = handleInfo->Handles[i];
|
||||
HANDLE dupHandle = NULL;
|
||||
POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
|
||||
PVOID objectNameInfo;
|
||||
UNICODE_STRING objectName;
|
||||
ULONG returnLength;
|
||||
fileFromWchar = NULL;
|
||||
arg = NULL;
|
||||
|
||||
/* Check if this handle belongs to the PID the user specified. */
|
||||
if (handle.ProcessId != pid)
|
||||
continue;
|
||||
|
||||
/* Skip handles with the following access codes as the next call
|
||||
to NtDuplicateObject() or NtQueryObject() might hang forever. */
|
||||
if((handle.GrantedAccess == 0x0012019f)
|
||||
|| (handle.GrantedAccess == 0x001a019f)
|
||||
|| (handle.GrantedAccess == 0x00120189)
|
||||
|| (handle.GrantedAccess == 0x00100000)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Duplicate the handle so we can query it. */
|
||||
if (!NT_SUCCESS(NtDuplicateObject(
|
||||
processHandle,
|
||||
handle.Handle,
|
||||
GetCurrentProcess(),
|
||||
&dupHandle,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
)))
|
||||
{
|
||||
//printf("[%#x] Error!\n", handle.Handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Query the object type. */
|
||||
objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
|
||||
if (!NT_SUCCESS(NtQueryObject(
|
||||
dupHandle,
|
||||
ObjectTypeInformation,
|
||||
objectTypeInfo,
|
||||
0x1000,
|
||||
NULL
|
||||
)))
|
||||
{
|
||||
//printf("[%#x] Error!\n", handle.Handle);
|
||||
free(objectTypeInfo);
|
||||
CloseHandle(dupHandle);
|
||||
continue;
|
||||
}
|
||||
|
||||
objectNameInfo = malloc(0x1000);
|
||||
if (!NT_SUCCESS(NtQueryObject(
|
||||
dupHandle,
|
||||
ObjectNameInformation,
|
||||
objectNameInfo,
|
||||
0x1000,
|
||||
&returnLength
|
||||
)))
|
||||
{
|
||||
/* Reallocate the buffer and try again. */
|
||||
objectNameInfo = realloc(objectNameInfo, returnLength);
|
||||
if (!NT_SUCCESS(NtQueryObject(
|
||||
dupHandle,
|
||||
ObjectNameInformation,
|
||||
objectNameInfo,
|
||||
returnLength,
|
||||
NULL
|
||||
)))
|
||||
{
|
||||
/* We have the type name, so just display that.*/
|
||||
/*
|
||||
printf(
|
||||
"[%#x] %.*S: (could not get name)\n",
|
||||
handle.Handle,
|
||||
objectTypeInfo->Name.Length / 2,
|
||||
objectTypeInfo->Name.Buffer
|
||||
);
|
||||
*/
|
||||
free(objectTypeInfo);
|
||||
free(objectNameInfo);
|
||||
CloseHandle(dupHandle);
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Cast our buffer into an UNICODE_STRING. */
|
||||
objectName = *(PUNICODE_STRING)objectNameInfo;
|
||||
|
||||
/* Print the information! */
|
||||
if (objectName.Length)
|
||||
{
|
||||
/* The object has a name. Make sure it is a file otherwise
|
||||
ignore it */
|
||||
fileNameLength = objectName.Length / 2;
|
||||
if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
|
||||
//printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
|
||||
fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
|
||||
fileNameLength);
|
||||
if (fileFromWchar == NULL)
|
||||
goto error_py_fun;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar));
|
||||
#else
|
||||
arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar));
|
||||
#endif
|
||||
if (!arg)
|
||||
goto error_py_fun;
|
||||
Py_XDECREF(fileFromWchar);
|
||||
fileFromWchar = NULL;
|
||||
if (PyList_Append(filesList, arg))
|
||||
goto error_py_fun;
|
||||
Py_XDECREF(arg);
|
||||
}
|
||||
/*
|
||||
printf(
|
||||
"[%#x] %.*S: %.*S\n",
|
||||
handle.Handle,
|
||||
objectTypeInfo->Name.Length / 2,
|
||||
objectTypeInfo->Name.Buffer,
|
||||
objectName.Length / 2,
|
||||
objectName.Buffer
|
||||
);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print something else. */
|
||||
/*
|
||||
printf(
|
||||
"[%#x] %.*S: (unnamed)\n",
|
||||
handle.Handle,
|
||||
objectTypeInfo->Name.Length / 2,
|
||||
objectTypeInfo->Name.Buffer
|
||||
);
|
||||
*/
|
||||
;;
|
||||
}
|
||||
free(objectTypeInfo);
|
||||
free(objectNameInfo);
|
||||
CloseHandle(dupHandle);
|
||||
}
|
||||
free(handleInfo);
|
||||
CloseHandle(processHandle);
|
||||
return filesList;
|
||||
|
||||
error_py_fun:
|
||||
Py_XDECREF(arg);
|
||||
Py_XDECREF(fileFromWchar);
|
||||
Py_DECREF(filesList);
|
||||
return NULL;
|
||||
}
|
12
vendor/psutil/arch/mswindows/process_handles.h
vendored
Normal file
12
vendor/psutil/arch/mswindows/process_handles.h
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* $Id: process_info.h 1060 2011-07-02 18:05:26Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <windows.h>
|
||||
|
||||
PyObject* get_open_files(long pid, HANDLE processHandle);
|
510
vendor/psutil/arch/mswindows/process_info.c
vendored
Normal file
510
vendor/psutil/arch/mswindows/process_info.c
vendored
Normal file
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* $Id: process_info.c 1463 2012-07-18 13:06:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Helper functions related to fetching process information. Used by
|
||||
* _psutil_mswindows module methods.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include "security.h"
|
||||
#include "process_info.h"
|
||||
#include "ntextapi.h"
|
||||
|
||||
/*
|
||||
* NtQueryInformationProcess code taken from
|
||||
* http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
|
||||
* typedefs needed to compile against ntdll functions not exposted in the API
|
||||
*/
|
||||
typedef LONG NTSTATUS;
|
||||
|
||||
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
|
||||
HANDLE ProcessHandle,
|
||||
DWORD ProcessInformationClass,
|
||||
PVOID ProcessInformation,
|
||||
DWORD ProcessInformationLength,
|
||||
PDWORD ReturnLength
|
||||
);
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION
|
||||
{
|
||||
PVOID Reserved1;
|
||||
PVOID PebBaseAddress;
|
||||
PVOID Reserved2[2];
|
||||
ULONG_PTR UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
|
||||
|
||||
|
||||
/*
|
||||
* A wrapper around OpenProcess setting NSP exception if process
|
||||
* no longer exists.
|
||||
* "pid" is the process pid, "dwDesiredAccess" is the first argument
|
||||
* exptected by OpenProcess.
|
||||
* Return a process handle or NULL.
|
||||
*/
|
||||
HANDLE
|
||||
handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
DWORD processExitCode = 0;
|
||||
|
||||
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 handle_from_pid_waccess but implicitly uses
|
||||
* PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
|
||||
* parameter for OpenProcess.
|
||||
*/
|
||||
HANDLE
|
||||
handle_from_pid(DWORD pid) {
|
||||
DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
|
||||
return handle_from_pid_waccess(pid, dwDesiredAccess);
|
||||
}
|
||||
|
||||
|
||||
// fetch the PEB base address from NtQueryInformationProcess()
|
||||
PVOID
|
||||
GetPebAddress(HANDLE ProcessHandle)
|
||||
{
|
||||
_NtQueryInformationProcess NtQueryInformationProcess =
|
||||
(_NtQueryInformationProcess)GetProcAddress(
|
||||
GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
|
||||
PROCESS_BASIC_INFORMATION pbi;
|
||||
|
||||
NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
|
||||
return pbi.PebBaseAddress;
|
||||
}
|
||||
|
||||
|
||||
DWORD*
|
||||
get_pids(DWORD *numberOfReturnedPIDs) {
|
||||
/* 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 (! 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
|
||||
pid_is_running(DWORD pid)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
DWORD exitCode;
|
||||
|
||||
// Special case for PID 0 System Idle Process
|
||||
if (pid == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pid < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
FALSE, pid);
|
||||
if (NULL == hProcess) {
|
||||
// invalid parameter is no such process
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER) {
|
||||
CloseHandle(hProcess);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// access denied obviously means there's a process to deny access to...
|
||||
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
||||
CloseHandle(hProcess);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (GetExitCodeProcess(hProcess, &exitCode)) {
|
||||
CloseHandle(hProcess);
|
||||
return (exitCode == STILL_ACTIVE);
|
||||
}
|
||||
|
||||
// access denied means there's a process there so we'll assume it's running
|
||||
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
||||
CloseHandle(hProcess);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
CloseHandle(hProcess);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pid_in_proclist(DWORD pid)
|
||||
{
|
||||
DWORD *proclist = NULL;
|
||||
DWORD numberOfReturnedPIDs;
|
||||
DWORD i;
|
||||
|
||||
proclist = get_pids(&numberOfReturnedPIDs);
|
||||
if (NULL == proclist) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < numberOfReturnedPIDs; i++) {
|
||||
if (pid == proclist[i]) {
|
||||
free(proclist);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
free(proclist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Check exit code from a process handle. Return FALSE on an error also
|
||||
BOOL is_running(HANDLE hProcess)
|
||||
{
|
||||
DWORD dwCode;
|
||||
|
||||
if (NULL == hProcess) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GetExitCodeProcess(hProcess, &dwCode)) {
|
||||
return (dwCode == STILL_ACTIVE);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Return None to represent NoSuchProcess, else return NULL for
|
||||
// other exception or the name as a Python string
|
||||
PyObject*
|
||||
get_name(long pid)
|
||||
{
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
PROCESSENTRY32 pe = { 0 };
|
||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
if( Process32First(h, &pe)) {
|
||||
do {
|
||||
if (pe.th32ProcessID == pid) {
|
||||
CloseHandle(h);
|
||||
return Py_BuildValue("s", pe.szExeFile);
|
||||
}
|
||||
} while(Process32Next(h, &pe));
|
||||
|
||||
// the process was never found, set NoSuchProcess exception
|
||||
NoSuchProcess();
|
||||
CloseHandle(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
return PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
|
||||
|
||||
/* returns parent pid (as a Python int) for given pid or None on failure */
|
||||
PyObject*
|
||||
get_ppid(long pid)
|
||||
{
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
PROCESSENTRY32 pe = { 0 };
|
||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
if( Process32First(h, &pe)) {
|
||||
do {
|
||||
if (pe.th32ProcessID == pid) {
|
||||
CloseHandle(h);
|
||||
return Py_BuildValue("I", pe.th32ParentProcessID);
|
||||
}
|
||||
} while(Process32Next(h, &pe));
|
||||
|
||||
// the process was never found, set NoSuchProcess exception
|
||||
NoSuchProcess();
|
||||
CloseHandle(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
return PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns a Python list representing the arguments for the process
|
||||
* with given pid or NULL on error.
|
||||
*/
|
||||
PyObject*
|
||||
get_arg_list(long pid)
|
||||
{
|
||||
int nArgs, i;
|
||||
LPWSTR *szArglist = 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 = handle_from_pid(pid);
|
||||
if(hProcess == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pebAddress = GetPebAddress(hProcess);
|
||||
|
||||
/* get the address of ProcessParameters */
|
||||
#ifdef _WIN64
|
||||
if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
|
||||
&rtlUserProcParamsAddress, sizeof(PVOID), NULL))
|
||||
#else
|
||||
if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
|
||||
&rtlUserProcParamsAddress, sizeof(PVOID), NULL))
|
||||
#endif
|
||||
{
|
||||
////printf("Could not read the address of ProcessParameters!\n");
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* read the CommandLine UNICODE_STRING structure */
|
||||
#ifdef _WIN64
|
||||
if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
|
||||
&commandLine, sizeof(commandLine), NULL))
|
||||
#else
|
||||
if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
|
||||
&commandLine, sizeof(commandLine), NULL))
|
||||
#endif
|
||||
{
|
||||
////printf("Could not read CommandLine!\n");
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/* allocate memory to hold the command line */
|
||||
commandLineContents = (WCHAR *)malloc(commandLine.Length+1);
|
||||
|
||||
/* read the command line */
|
||||
if (!ReadProcessMemory(hProcess, commandLine.Buffer,
|
||||
commandLineContents, commandLine.Length, NULL))
|
||||
{
|
||||
////printf("Could not read the command line string!\n");
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* print the commandline */
|
||||
////printf("%.*S\n", commandLine.Length / 2, commandLineContents);
|
||||
|
||||
// null-terminate the string to prevent wcslen from returning incorrect length
|
||||
// the length specifier is in characters, but commandLine.Length is in bytes
|
||||
commandLineContents[(commandLine.Length/sizeof(WCHAR))] = '\0';
|
||||
|
||||
// attemempt tp parse the command line using Win32 API, fall back on string
|
||||
// cmdline version otherwise
|
||||
szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
|
||||
if (NULL == szArglist) {
|
||||
// failed to parse arglist
|
||||
// encode as a UTF8 Python string object from WCHAR string
|
||||
arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
|
||||
commandLine.Length / 2);
|
||||
if (arg_from_wchar == NULL)
|
||||
goto error;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
|
||||
#else
|
||||
argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
|
||||
#endif
|
||||
if (!argList)
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
// arglist parsed as array of UNICODE_STRING, so convert each to Python
|
||||
// string object and add to arg list
|
||||
argList = Py_BuildValue("[]");
|
||||
if (!argList)
|
||||
goto error;
|
||||
for(i=0; i<nArgs; i++) {
|
||||
arg_from_wchar = NULL;
|
||||
arg = NULL;
|
||||
////printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]),
|
||||
// szArglist[i], wcslen(szArglist[i]));
|
||||
arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
|
||||
wcslen(szArglist[i])
|
||||
);
|
||||
if (arg_from_wchar == NULL)
|
||||
goto error;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
arg = PyUnicode_FromObject(arg_from_wchar);
|
||||
#else
|
||||
arg = PyUnicode_AsUTF8String(arg_from_wchar);
|
||||
#endif
|
||||
if (arg == NULL)
|
||||
goto error;
|
||||
Py_XDECREF(arg_from_wchar);
|
||||
if (PyList_Append(argList, arg))
|
||||
goto error;
|
||||
Py_XDECREF(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (szArglist != NULL)
|
||||
LocalFree(szArglist);
|
||||
free(commandLineContents);
|
||||
CloseHandle(hProcess);
|
||||
return argList;
|
||||
|
||||
error:
|
||||
Py_XDECREF(arg);
|
||||
Py_XDECREF(arg_from_wchar);
|
||||
Py_XDECREF(argList);
|
||||
if (hProcess != NULL)
|
||||
CloseHandle(hProcess);
|
||||
if (commandLineContents != NULL)
|
||||
free(commandLineContents);
|
||||
if (szArglist != NULL)
|
||||
LocalFree(szArglist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#define PH_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
|
||||
|
||||
#define PH_NEXT_PROCESS(Process) ( \
|
||||
((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
|
||||
(PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
|
||||
((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
|
||||
NULL \
|
||||
)
|
||||
|
||||
const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
|
||||
const STATUS_BUFFER_TOO_SMALL = 0xC0000023L;
|
||||
|
||||
/*
|
||||
* Given a process PID and a PSYSTEM_PROCESS_INFORMATION structure
|
||||
* fills the structure with process information.
|
||||
* On success return 1, else 0 with Python exception already set.
|
||||
*/
|
||||
int
|
||||
get_process_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess, PVOID *retBuffer)
|
||||
{
|
||||
static ULONG initialBufferSize = 0x4000;
|
||||
NTSTATUS status;
|
||||
PVOID buffer;
|
||||
ULONG bufferSize;
|
||||
PSYSTEM_PROCESS_INFORMATION process;
|
||||
|
||||
// get NtQuerySystemInformation
|
||||
typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
|
||||
NTQSI_PROC NtQuerySystemInformation;
|
||||
HINSTANCE hNtDll;
|
||||
hNtDll = LoadLibrary(TEXT("ntdll.dll"));
|
||||
NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
|
||||
hNtDll, "NtQuerySystemInformation");
|
||||
|
||||
bufferSize = initialBufferSize;
|
||||
buffer = malloc(bufferSize);
|
||||
|
||||
while (TRUE) {
|
||||
status = NtQuerySystemInformation(SystemProcessInformation, buffer,
|
||||
bufferSize, &bufferSize);
|
||||
|
||||
if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
free(buffer);
|
||||
buffer = malloc(bufferSize);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
|
||||
FreeLibrary(hNtDll);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bufferSize <= 0x20000) {
|
||||
initialBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
process = PH_FIRST_PROCESS(buffer);
|
||||
do {
|
||||
if (process->UniqueProcessId == (HANDLE)pid) {
|
||||
*retProcess = process;
|
||||
*retBuffer = buffer;
|
||||
return 1;
|
||||
}
|
||||
} while ( (process = PH_NEXT_PROCESS(process)) );
|
||||
|
||||
NoSuchProcess();
|
||||
FreeLibrary(hNtDll);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
25
vendor/psutil/arch/mswindows/process_info.h
vendored
Normal file
25
vendor/psutil/arch/mswindows/process_info.h
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* $Id: process_info.h 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Helper functions related to fetching process information. Used by _psutil_mswindows
|
||||
* module methods.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <windows.h>
|
||||
|
||||
HANDLE handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
|
||||
HANDLE handle_from_pid(DWORD pid);
|
||||
PVOID GetPebAddress(HANDLE ProcessHandle);
|
||||
HANDLE handle_from_pid(DWORD pid);
|
||||
BOOL is_running(HANDLE hProcess);
|
||||
int pid_in_proclist(DWORD pid);
|
||||
int pid_is_running(DWORD pid);
|
||||
PyObject* get_arg_list(long pid);
|
||||
PyObject* get_ppid(long pid);
|
||||
PyObject* get_name(long pid);
|
||||
DWORD* get_pids(DWORD *numberOfReturnedPIDs);
|
240
vendor/psutil/arch/mswindows/security.c
vendored
Normal file
240
vendor/psutil/arch/mswindows/security.c
vendored
Normal file
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* $Id: security.c 1296 2012-04-25 01:29:43Z david.daeschler@gmail.com $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Security related functions for Windows platform (Set privileges such as
|
||||
* SeDebug), as well as security helper functions.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <Python.h>
|
||||
|
||||
/*
|
||||
* Convert a process handle to a process token handle.
|
||||
*/
|
||||
HANDLE
|
||||
token_from_handle(HANDLE hProcess) {
|
||||
HANDLE hToken = NULL;
|
||||
|
||||
if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) ) {
|
||||
return PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
|
||||
return hToken;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* http://www.ddj.com/windows/184405986
|
||||
*
|
||||
* There's a way to determine whether we're running under the Local System
|
||||
* account. However (you guessed it), we have to call more Win32 functions to
|
||||
* determine this. Backing up through the code listing, we need to make another
|
||||
* call to GetTokenInformation, but instead of passing through the TOKEN_USER
|
||||
* constant, we pass through the TOKEN_PRIVILEGES constant. This value returns
|
||||
* an array of privileges that the account has in the environment. Iterating
|
||||
* through the array, we call the function LookupPrivilegeName looking for the
|
||||
* string “SeTcbPrivilege. If the function returns this string, then this
|
||||
* account has Local System privileges
|
||||
*/
|
||||
int HasSystemPrivilege(HANDLE hProcess) {
|
||||
DWORD i;
|
||||
DWORD dwSize = 0;
|
||||
DWORD dwRetval = 0;
|
||||
TCHAR privName[256];
|
||||
DWORD dwNameSize = 256;
|
||||
//PTOKEN_PRIVILEGES tp = NULL;
|
||||
BYTE *pBuffer = NULL;
|
||||
TOKEN_PRIVILEGES* tp = NULL;
|
||||
HANDLE hToken = token_from_handle(hProcess);
|
||||
|
||||
if (NULL == hToken) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// call GetTokenInformation first to get the buffer size
|
||||
if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) {
|
||||
dwRetval = GetLastError();
|
||||
// if it failed for a reason other than the buffer, bail out
|
||||
if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) {
|
||||
PyErr_SetFromWindowsErr(dwRetval);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate buffer and call GetTokenInformation again
|
||||
//tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
|
||||
pBuffer = (BYTE *) malloc(dwSize);
|
||||
|
||||
if (pBuffer == NULL) {
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
free(pBuffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwSize, &dwSize) ) {
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
free(pBuffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer
|
||||
tp = (TOKEN_PRIVILEGES*)pBuffer;
|
||||
|
||||
// check all the privileges looking for SeTcbPrivilege
|
||||
for(i=0; i < tp->PrivilegeCount; i++) {
|
||||
// reset the buffer contents and the buffer size
|
||||
strcpy(privName, "");
|
||||
dwNameSize = sizeof(privName) / sizeof(TCHAR);
|
||||
if (! LookupPrivilegeName(NULL,
|
||||
&tp->Privileges[i].Luid,
|
||||
(LPTSTR)privName,
|
||||
&dwNameSize)) {
|
||||
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
free(pBuffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if we find the SeTcbPrivilege then it's a LocalSystem process
|
||||
if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) {
|
||||
free(pBuffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
} //for
|
||||
|
||||
free(pBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
|
||||
{
|
||||
TOKEN_PRIVILEGES tp;
|
||||
LUID luid;
|
||||
TOKEN_PRIVILEGES tpPrevious;
|
||||
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
|
||||
|
||||
if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
|
||||
|
||||
// first pass. get current privilege setting
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = 0;
|
||||
|
||||
AdjustTokenPrivileges(
|
||||
hToken,
|
||||
FALSE,
|
||||
&tp,
|
||||
sizeof(TOKEN_PRIVILEGES),
|
||||
&tpPrevious,
|
||||
&cbPrevious
|
||||
);
|
||||
|
||||
if (GetLastError() != ERROR_SUCCESS) return FALSE;
|
||||
|
||||
// second pass. set privilege based on previous setting
|
||||
tpPrevious.PrivilegeCount = 1;
|
||||
tpPrevious.Privileges[0].Luid = luid;
|
||||
|
||||
if(bEnablePrivilege) {
|
||||
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
|
||||
}
|
||||
|
||||
else {
|
||||
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
|
||||
tpPrevious.Privileges[0].Attributes);
|
||||
}
|
||||
|
||||
AdjustTokenPrivileges(
|
||||
hToken,
|
||||
FALSE,
|
||||
&tpPrevious,
|
||||
cbPrevious,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (GetLastError() != ERROR_SUCCESS) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int SetSeDebug()
|
||||
{
|
||||
HANDLE hToken;
|
||||
if(! OpenThreadToken(GetCurrentThread(),
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||||
FALSE,
|
||||
&hToken)
|
||||
){
|
||||
if (GetLastError() == ERROR_NO_TOKEN){
|
||||
if (!ImpersonateSelf(SecurityImpersonation)){
|
||||
CloseHandle(hToken);
|
||||
return 0;
|
||||
}
|
||||
if (!OpenThreadToken(GetCurrentThread(),
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||||
FALSE,
|
||||
&hToken)
|
||||
){
|
||||
RevertToSelf();
|
||||
CloseHandle(hToken);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enable SeDebugPrivilege (open any process)
|
||||
if (! SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)){
|
||||
RevertToSelf();
|
||||
CloseHandle(hToken);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RevertToSelf();
|
||||
CloseHandle(hToken);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int UnsetSeDebug()
|
||||
{
|
||||
HANDLE hToken;
|
||||
if(! OpenThreadToken(GetCurrentThread(),
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||||
FALSE,
|
||||
&hToken)
|
||||
){
|
||||
if(GetLastError() == ERROR_NO_TOKEN){
|
||||
if(! ImpersonateSelf(SecurityImpersonation)){
|
||||
//Log2File("Error setting impersonation! [UnsetSeDebug()]", L_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!OpenThreadToken(GetCurrentThread(),
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||||
FALSE,
|
||||
&hToken)
|
||||
){
|
||||
//Log2File("Error Opening Thread Token! [UnsetSeDebug()]", L_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now disable SeDebug
|
||||
if(!SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)){
|
||||
//Log2File("Error unsetting SeDebug Privilege [SetPrivilege()]", L_WARN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CloseHandle(hToken);
|
||||
return 1;
|
||||
}
|
||||
|
20
vendor/psutil/arch/mswindows/security.h
vendored
Normal file
20
vendor/psutil/arch/mswindows/security.h
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* $Id: security.h 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Security related functions for Windows platform (Set privileges such as
|
||||
* SeDebug), as well as security helper functions.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege);
|
||||
int SetSeDebug();
|
||||
int UnsetSeDebug();
|
||||
HANDLE token_from_handle(HANDLE hProcess);
|
||||
int HasSystemPrivilege(HANDLE hProcess);
|
||||
|
295
vendor/psutil/arch/osx/process_info.c
vendored
Normal file
295
vendor/psutil/arch/osx/process_info.c
vendored
Normal file
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* $Id: process_info.c 1460 2012-07-18 02:49:24Z g.rodola@gmail.com $
|
||||
*
|
||||
* 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
|
||||
pid_exists(long pid)
|
||||
{
|
||||
int kill_ret;
|
||||
|
||||
// save some time if it's an invalid PID
|
||||
if (pid < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if kill returns success of permission denied we know it's a valid PID
|
||||
kill_ret = kill(pid , 0);
|
||||
if ( (0 == kill_ret) || (EPERM == errno) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// otherwise return 0 for PID not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Returns a list of all BSD processes on the system. This routine
|
||||
* allocates the list and puts it in *procList and a count of the
|
||||
* number of entries in *procCount. You are responsible for freeing
|
||||
* this list (use "free" from System framework).
|
||||
* On success, the function returns 0.
|
||||
* On error, the function returns a BSD errno value.
|
||||
*/
|
||||
int
|
||||
get_proc_list(kinfo_proc **procList, size_t *procCount)
|
||||
{
|
||||
/* Declaring mib as const requires use of a cast since the
|
||||
* sysctl prototype doesn't include the const modifier. */
|
||||
static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
|
||||
size_t size, size2;
|
||||
void *ptr;
|
||||
int err, lim = 8; /* some limit */
|
||||
|
||||
assert( procList != NULL);
|
||||
assert(*procList == NULL);
|
||||
assert(procCount != NULL);
|
||||
|
||||
*procCount = 0;
|
||||
|
||||
/* We start by calling sysctl with ptr == NULL and size == 0.
|
||||
* That will succeed, and set size to the appropriate length.
|
||||
* We then allocate a buffer of at least that size and call
|
||||
* sysctl with that buffer. If that succeeds, we're done.
|
||||
* If that call fails with ENOMEM, we throw the buffer away
|
||||
* and try again.
|
||||
* Note that the loop calls sysctl with NULL again. This is
|
||||
* is necessary because the ENOMEM failure case sets size to
|
||||
* the amount of data returned, not the amount of data that
|
||||
* could have been returned.
|
||||
*/
|
||||
while (lim-- > 0) {
|
||||
size = 0;
|
||||
if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
size2 = size + (size >> 3); /* add some */
|
||||
if (size2 > size) {
|
||||
ptr = malloc(size2);
|
||||
if (ptr == NULL) {
|
||||
ptr = malloc(size);
|
||||
} else {
|
||||
size = size2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = malloc(size);
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) {
|
||||
err = errno;
|
||||
free(ptr);
|
||||
if (err != ENOMEM) {
|
||||
return err;
|
||||
}
|
||||
|
||||
} else {
|
||||
*procList = (kinfo_proc *)ptr;
|
||||
*procCount = size / sizeof(kinfo_proc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
/* Read the maximum argument size for processes */
|
||||
int
|
||||
get_argmax()
|
||||
{
|
||||
int argmax;
|
||||
int mib[] = { CTL_KERN, KERN_ARGMAX };
|
||||
size_t size = sizeof(argmax);
|
||||
|
||||
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0) {
|
||||
return argmax;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* return process args as a python list */
|
||||
PyObject*
|
||||
get_arg_list(long pid)
|
||||
{
|
||||
int mib[3];
|
||||
int nargs;
|
||||
int len;
|
||||
char *procargs = 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 = 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) { // invalid == access denied OR nonexistent PID
|
||||
if ( 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
|
||||
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 (! pid_exists(pid)) {
|
||||
NoSuchProcess();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
AccessDenied();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (ret != size) {
|
||||
AccessDenied();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
22
vendor/psutil/arch/osx/process_info.h
vendored
Normal file
22
vendor/psutil/arch/osx/process_info.h
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* $Id: process_info.h 1407 2012-06-30 17:14:54Z g.rodola@gmail.com $
|
||||
*
|
||||
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* Helper functions related to fetching process information. Used by _psutil_osx
|
||||
* module methods.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
|
||||
typedef struct kinfo_proc kinfo_proc;
|
||||
|
||||
int get_proc_list(kinfo_proc **procList, size_t *procCount);
|
||||
int get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
|
||||
int get_argmax(void);
|
||||
int pid_exists(long pid);
|
||||
int psutil_proc_pidinfo(long pid, int flavor, void *pti, int size);
|
||||
PyObject* get_arg_list(long pid);
|
73
vendor/psutil/error.py
vendored
Normal file
73
vendor/psutil/error.py
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# $Id: error.py 1142 2011-10-05 18:45:49Z g.rodola $
|
||||
#
|
||||
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""psutil exception classes; do not import this directly"""
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
"""Base exception class. All other psutil exceptions inherit
|
||||
from this one.
|
||||
"""
|
||||
|
||||
class NoSuchProcess(Error):
|
||||
"""Exception raised when a process with a certain PID doesn't
|
||||
or no longer exists (zombie).
|
||||
"""
|
||||
|
||||
def __init__(self, pid, name=None, msg=None):
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
self.msg = msg
|
||||
if msg is None:
|
||||
if name:
|
||||
details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
|
||||
else:
|
||||
details = "(pid=%s)" % self.pid
|
||||
self.msg = "process no longer exists " + details
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
|
||||
class AccessDenied(Error):
|
||||
"""Exception raised when permission to perform an action is denied."""
|
||||
|
||||
def __init__(self, pid=None, name=None, msg=None):
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
self.msg = msg
|
||||
if msg is None:
|
||||
if (pid is not None) and (name is not None):
|
||||
self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
|
||||
elif (pid is not None):
|
||||
self.msg = "(pid=%s)" % self.pid
|
||||
else:
|
||||
self.msg = ""
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
|
||||
class TimeoutExpired(Error):
|
||||
"""Raised on Process.wait(timeout) if timeout expires and process
|
||||
is still alive.
|
||||
"""
|
||||
|
||||
def __init__(self, pid=None, name=None):
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
if (pid is not None) and (name is not None):
|
||||
self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
|
||||
elif (pid is not None):
|
||||
self.msg = "(pid=%s)" % self.pid
|
||||
else:
|
||||
self.msg = ""
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
Loading…
Add table
Reference in a new issue