pkgsrc-ng/sysutils/py-psutil/patches/patch-psutil___psnetbsd.py
2014-08-11 13:27:10 +02:00

375 lines
13 KiB
Python

$NetBSD: patch-psutil___psnetbsd.py,v 1.1 2013/10/12 13:32:36 wiz Exp $
Port to NetBSD.
--- psutil/_psnetbsd.py.orig 2013-10-12 13:19:29.000000000 +0000
+++ psutil/_psnetbsd.py
@@ -0,0 +1,367 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""NetBSD platform implementation."""
+
+import errno
+import os
+import sys
+import warnings
+
+import _psutil_netbsd
+import _psutil_posix
+from psutil import _psposix
+from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+from psutil._compat import namedtuple, wraps
+from psutil._common import *
+
+__extra__all__ = []
+
+# --- constants
+
+# Since these constants get determined at import time we do not want to
+# crash immediately; instead we'll set them to None and most likely
+# we'll crash later as they're used for determining process CPU stats
+# and creation_time
+try:
+ NUM_CPUS = _psutil_netbsd.get_num_cpus()
+except Exception:
+ NUM_CPUS = None
+ warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+try:
+ TOTAL_PHYMEM = _psutil_netbsd.get_virtual_mem()[0]
+except Exception:
+ TOTAL_PHYMEM = None
+ warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+try:
+ BOOT_TIME = _psutil_netbsd.get_system_boot_time()
+except Exception:
+ BOOT_TIME = None
+ warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+
+
+_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle irq')
+
+# --- public functions
+
+get_system_boot_time = _psutil_netbsd.get_system_boot_time
+
+nt_virtmem_info = namedtuple('vmem', ' '.join([
+ # all platforms
+ 'total', 'available', 'percent', 'used', 'free',
+ # *BSD specific
+ 'active',
+ 'inactive',
+ 'shared',
+ 'wired']))
+
+def virtual_memory():
+ """System virtual memory as a namedutple."""
+ mem = _psutil_netbsd.get_virtual_mem()
+ total, free, active, inactive, wired, shared = mem
+ avail = inactive + free
+ used = active + wired
+ percent = usage_percent((total - avail), total, _round=1)
+ return nt_virtmem_info(total, avail, percent, used, free,
+ active, inactive, 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_netbsd.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_netbsd.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_netbsd.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
+
+# \todo: check this
+# 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_netbsd, "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_netbsd.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_netbsd.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_netbsd.get_pid_list
+pid_exists = _psposix.pid_exists
+get_disk_usage = _psposix.get_disk_usage
+net_io_counters = _psutil_netbsd.get_net_io_counters
+disk_io_counters = _psutil_netbsd.get_disk_io_counters
+
+
+def wrap_exceptions(fun):
+ """Decorator which translates bare OSError exceptions into
+ NoSuchProcess and AccessDenied.
+ """
+ @wraps(fun)
+ def wrapper(self, *args, **kwargs):
+ try:
+ return fun(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_netbsd.SSTOP : STATUS_STOPPED,
+ _psutil_netbsd.SIDL : STATUS_IDLE,
+ _psutil_netbsd.SACTIVE : STATUS_RUNNING,
+# \todo: to what to map this?
+# _psutil_netbsd.SDYING : STATUS_IDLE,
+ _psutil_netbsd.SDEAD : STATUS_DEAD,
+ _psutil_netbsd.SZOMB : STATUS_ZOMBIE,
+}
+
+_conn_status_map = {_psutil_netbsd.TCPS_ESTABLISHED : CONN_ESTABLISHED,
+ _psutil_netbsd.TCPS_SYN_SENT : CONN_SYN_SENT,
+ _psutil_netbsd.TCPS_SYN_RECEIVED : CONN_SYN_RECV,
+ _psutil_netbsd.TCPS_FIN_WAIT_1 : CONN_FIN_WAIT1,
+ _psutil_netbsd.TCPS_FIN_WAIT_2 : CONN_FIN_WAIT2,
+ _psutil_netbsd.TCPS_TIME_WAIT : CONN_TIME_WAIT,
+ _psutil_netbsd.TCPS_CLOSED : CONN_CLOSE,
+ _psutil_netbsd.TCPS_CLOSE_WAIT : CONN_CLOSE_WAIT,
+ _psutil_netbsd.TCPS_LAST_ACK : CONN_LAST_ACK,
+ _psutil_netbsd.TCPS_LISTEN : CONN_LISTEN,
+ _psutil_netbsd.TCPS_CLOSING : CONN_CLOSING,
+ }
+
+
+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_netbsd.get_process_name(self.pid)
+
+ @wrap_exceptions
+ def get_process_exe(self):
+ """Return process executable pathname."""
+ return _psutil_netbsd.get_process_exe(self.pid)
+
+ @wrap_exceptions
+ def get_process_cmdline(self):
+ """Return process cmdline as a list of arguments."""
+ return _psutil_netbsd.get_process_cmdline(self.pid)
+
+ @wrap_exceptions
+ def get_process_terminal(self):
+ tty_nr = _psutil_netbsd.get_process_tty_nr(self.pid)
+ tmap = _psposix._get_terminal_map()
+ try:
+ return tmap[tty_nr]
+ except KeyError:
+ return None
+
+ @wrap_exceptions
+ def get_process_ppid(self):
+ """Return process parent pid."""
+ return _psutil_netbsd.get_process_ppid(self.pid)
+
+ # XXX - available on FreeBSD >= 8 only
+ if hasattr(_psutil_netbsd, "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_netbsd.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_netbsd.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_netbsd.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_netbsd.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_netbsd.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_netbsd.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_netbsd.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_netbsd.get_process_num_threads(self.pid)
+
+ @wrap_exceptions
+ def get_num_ctx_switches(self):
+ return nt_ctxsw(*_psutil_netbsd.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_netbsd.get_process_num_fds(self.pid)
+
+ @wrap_exceptions
+ def get_process_threads(self):
+ """Return the number of threads belonging to the process."""
+ rawlist = _psutil_netbsd.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_netbsd, "get_process_open_files"):
+ rawlist = _psutil_netbsd.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]
+ rawlist = _psutil_netbsd.get_process_connections(self.pid, families,
+ types)
+ ret = []
+ for item in rawlist:
+ fd, fam, type, laddr, raddr, status = item
+ status = _conn_status_map[status]
+ nt = nt_connection(fd, fam, type, laddr, raddr, status)
+ ret.append(nt)
+ return 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_netbsd.get_process_status(self.pid)
+ if code in _status_map:
+ return _status_map[code]
+ # XXX is this legit? will we even ever get here?
+ return "?"
+
+ @wrap_exceptions
+ def get_process_io_counters(self):
+ rc, wc, rb, wb = _psutil_netbsd.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_netbsd.get_process_memory_maps(self.pid)
+
+ # FreeBSD < 8 does not support kinfo_getfile() and kinfo_getvmmap()
+ if not hasattr(_psutil_netbsd, '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