mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-31 22:20:12 +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
|
import math
|
||||||
|
|
||||||
GIGS_OF_MEMORY = psutil.TOTAL_PHYMEM/1024/1024/1024.
|
GIGS_OF_MEMORY = psutil.TOTAL_PHYMEM/1024/1024/1024.
|
||||||
|
|
|
@ -22,7 +22,6 @@ lxml==3.1.0
|
||||||
mongoengine==0.8.2
|
mongoengine==0.8.2
|
||||||
nltk==2.0.4
|
nltk==2.0.4
|
||||||
oauth2==1.5.211
|
oauth2==1.5.211
|
||||||
psutil==0.6.1
|
|
||||||
pyes==0.19.1
|
pyes==0.19.1
|
||||||
pyelasticsearch==0.5
|
pyelasticsearch==0.5
|
||||||
pyflakes==0.6.1
|
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