Mercurial > repos > shellac > guppy_basecaller
diff env/lib/python3.7/site-packages/psutil/_psbsd.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/psutil/_psbsd.py Thu May 14 16:47:39 2020 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,903 +0,0 @@ -# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""FreeBSD, OpenBSD and NetBSD platforms implementation.""" - -import contextlib -import errno -import functools -import os -import xml.etree.ElementTree as ET -from collections import namedtuple -from collections import defaultdict - -from . import _common -from . import _psposix -from . import _psutil_bsd as cext -from . import _psutil_posix as cext_posix -from ._common import AccessDenied -from ._common import conn_tmap -from ._common import conn_to_ntuple -from ._common import FREEBSD -from ._common import memoize -from ._common import memoize_when_activated -from ._common import NETBSD -from ._common import NoSuchProcess -from ._common import OPENBSD -from ._common import usage_percent -from ._common import ZombieProcess -from ._compat import FileNotFoundError -from ._compat import PermissionError -from ._compat import ProcessLookupError -from ._compat import which - - -__extra__all__ = [] - - -# ===================================================================== -# --- globals -# ===================================================================== - - -if FREEBSD: - PROC_STATUSES = { - cext.SIDL: _common.STATUS_IDLE, - cext.SRUN: _common.STATUS_RUNNING, - cext.SSLEEP: _common.STATUS_SLEEPING, - cext.SSTOP: _common.STATUS_STOPPED, - cext.SZOMB: _common.STATUS_ZOMBIE, - cext.SWAIT: _common.STATUS_WAITING, - cext.SLOCK: _common.STATUS_LOCKED, - } -elif OPENBSD or NETBSD: - PROC_STATUSES = { - cext.SIDL: _common.STATUS_IDLE, - cext.SSLEEP: _common.STATUS_SLEEPING, - cext.SSTOP: _common.STATUS_STOPPED, - # According to /usr/include/sys/proc.h SZOMB is unused. - # test_zombie_process() shows that SDEAD is the right - # equivalent. Also it appears there's no equivalent of - # psutil.STATUS_DEAD. SDEAD really means STATUS_ZOMBIE. - # cext.SZOMB: _common.STATUS_ZOMBIE, - cext.SDEAD: _common.STATUS_ZOMBIE, - cext.SZOMB: _common.STATUS_ZOMBIE, - # From http://www.eecs.harvard.edu/~margo/cs161/videos/proc.h.txt - # OpenBSD has SRUN and SONPROC: SRUN indicates that a process - # is runnable but *not* yet running, i.e. is on a run queue. - # SONPROC indicates that the process is actually executing on - # a CPU, i.e. it is no longer on a run queue. - # As such we'll map SRUN to STATUS_WAKING and SONPROC to - # STATUS_RUNNING - cext.SRUN: _common.STATUS_WAKING, - cext.SONPROC: _common.STATUS_RUNNING, - } -elif NETBSD: - PROC_STATUSES = { - cext.SIDL: _common.STATUS_IDLE, - cext.SACTIVE: _common.STATUS_RUNNING, - cext.SDYING: _common.STATUS_ZOMBIE, - cext.SSTOP: _common.STATUS_STOPPED, - cext.SZOMB: _common.STATUS_ZOMBIE, - cext.SDEAD: _common.STATUS_DEAD, - cext.SSUSPENDED: _common.STATUS_SUSPENDED, # unique to NetBSD - } - -TCP_STATUSES = { - cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, - cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT, - cext.TCPS_SYN_RECEIVED: _common.CONN_SYN_RECV, - cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1, - cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2, - cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT, - cext.TCPS_CLOSED: _common.CONN_CLOSE, - cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT, - cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK, - cext.TCPS_LISTEN: _common.CONN_LISTEN, - cext.TCPS_CLOSING: _common.CONN_CLOSING, - cext.PSUTIL_CONN_NONE: _common.CONN_NONE, -} - -if NETBSD: - PAGESIZE = os.sysconf("SC_PAGESIZE") -else: - PAGESIZE = os.sysconf("SC_PAGE_SIZE") -AF_LINK = cext_posix.AF_LINK - -HAS_PER_CPU_TIMES = hasattr(cext, "per_cpu_times") -HAS_PROC_NUM_THREADS = hasattr(cext, "proc_num_threads") -HAS_PROC_OPEN_FILES = hasattr(cext, 'proc_open_files') -HAS_PROC_NUM_FDS = hasattr(cext, 'proc_num_fds') - -kinfo_proc_map = dict( - ppid=0, - status=1, - real_uid=2, - effective_uid=3, - saved_uid=4, - real_gid=5, - effective_gid=6, - saved_gid=7, - ttynr=8, - create_time=9, - ctx_switches_vol=10, - ctx_switches_unvol=11, - read_io_count=12, - write_io_count=13, - user_time=14, - sys_time=15, - ch_user_time=16, - ch_sys_time=17, - rss=18, - vms=19, - memtext=20, - memdata=21, - memstack=22, - cpunum=23, - name=24, -) - - -# ===================================================================== -# --- named tuples -# ===================================================================== - - -# psutil.virtual_memory() -svmem = namedtuple( - 'svmem', ['total', 'available', 'percent', 'used', 'free', - 'active', 'inactive', 'buffers', 'cached', 'shared', 'wired']) -# psutil.cpu_times() -scputimes = namedtuple( - 'scputimes', ['user', 'nice', 'system', 'idle', 'irq']) -# psutil.Process.memory_info() -pmem = namedtuple('pmem', ['rss', 'vms', 'text', 'data', 'stack']) -# psutil.Process.memory_full_info() -pfullmem = pmem -# psutil.Process.cpu_times() -pcputimes = namedtuple('pcputimes', - ['user', 'system', 'children_user', 'children_system']) -# psutil.Process.memory_maps(grouped=True) -pmmap_grouped = namedtuple( - 'pmmap_grouped', 'path rss, private, ref_count, shadow_count') -# psutil.Process.memory_maps(grouped=False) -pmmap_ext = namedtuple( - 'pmmap_ext', 'addr, perms path rss, private, ref_count, shadow_count') -# psutil.disk_io_counters() -if FREEBSD: - sdiskio = namedtuple('sdiskio', ['read_count', 'write_count', - 'read_bytes', 'write_bytes', - 'read_time', 'write_time', - 'busy_time']) -else: - sdiskio = namedtuple('sdiskio', ['read_count', 'write_count', - 'read_bytes', 'write_bytes']) - - -# ===================================================================== -# --- memory -# ===================================================================== - - -def virtual_memory(): - """System virtual memory as a namedtuple.""" - mem = cext.virtual_mem() - total, free, active, inactive, wired, cached, buffers, shared = mem - if NETBSD: - # On NetBSD buffers and shared mem is determined via /proc. - # The C ext set them to 0. - with open('/proc/meminfo', 'rb') as f: - for line in f: - if line.startswith(b'Buffers:'): - buffers = int(line.split()[1]) * 1024 - elif line.startswith(b'MemShared:'): - shared = int(line.split()[1]) * 1024 - avail = inactive + cached + free - used = active + wired + cached - percent = usage_percent((total - avail), total, round_=1) - return svmem(total, avail, percent, used, free, - active, inactive, buffers, cached, shared, wired) - - -def swap_memory(): - """System swap memory as (total, used, free, sin, sout) namedtuple.""" - total, used, free, sin, sout = cext.swap_mem() - percent = usage_percent(used, total, round_=1) - return _common.sswap(total, used, free, percent, sin, sout) - - -# ===================================================================== -# --- CPU -# ===================================================================== - - -def cpu_times(): - """Return system per-CPU times as a namedtuple""" - user, nice, system, idle, irq = cext.cpu_times() - return scputimes(user, nice, system, idle, irq) - - -if HAS_PER_CPU_TIMES: - def per_cpu_times(): - """Return system CPU times as a namedtuple""" - ret = [] - for cpu_t in cext.per_cpu_times(): - user, nice, system, idle, irq = cpu_t - item = scputimes(user, nice, system, idle, irq) - ret.append(item) - return ret -else: - # XXX - # Ok, this is very dirty. - # On FreeBSD < 8 we cannot gather per-cpu information, see: - # https://github.com/giampaolo/psutil/issues/226 - # If num cpus > 1, on first call we return single cpu times to avoid a - # crash at psutil import time. - # Next calls will fail with NotImplementedError - def per_cpu_times(): - """Return system CPU times as a namedtuple""" - if cpu_count_logical() == 1: - return [cpu_times()] - if per_cpu_times.__called__: - raise NotImplementedError("supported only starting from FreeBSD 8") - per_cpu_times.__called__ = True - return [cpu_times()] - - per_cpu_times.__called__ = False - - -def cpu_count_logical(): - """Return the number of logical CPUs in the system.""" - return cext.cpu_count_logical() - - -if OPENBSD or NETBSD: - def cpu_count_physical(): - # OpenBSD and NetBSD do not implement this. - return 1 if cpu_count_logical() == 1 else None -else: - def cpu_count_physical(): - """Return the number of physical CPUs in the system.""" - # From the C module we'll get an XML string similar to this: - # http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html - # We may get None in case "sysctl kern.sched.topology_spec" - # is not supported on this BSD version, in which case we'll mimic - # os.cpu_count() and return None. - ret = None - s = cext.cpu_count_phys() - if s is not None: - # get rid of padding chars appended at the end of the string - index = s.rfind("</groups>") - if index != -1: - s = s[:index + 9] - root = ET.fromstring(s) - try: - ret = len(root.findall('group/children/group/cpu')) or None - finally: - # needed otherwise it will memleak - root.clear() - if not ret: - # If logical CPUs are 1 it's obvious we'll have only 1 - # physical CPU. - if cpu_count_logical() == 1: - return 1 - return ret - - -def cpu_stats(): - """Return various CPU stats as a named tuple.""" - if FREEBSD: - # Note: the C ext is returning some metrics we are not exposing: - # traps. - ctxsw, intrs, soft_intrs, syscalls, traps = cext.cpu_stats() - elif NETBSD: - # XXX - # Note about intrs: the C extension returns 0. intrs - # can be determined via /proc/stat; it has the same value as - # soft_intrs thought so the kernel is faking it (?). - # - # Note about syscalls: the C extension always sets it to 0 (?). - # - # Note: the C ext is returning some metrics we are not exposing: - # traps, faults and forks. - ctxsw, intrs, soft_intrs, syscalls, traps, faults, forks = \ - cext.cpu_stats() - with open('/proc/stat', 'rb') as f: - for line in f: - if line.startswith(b'intr'): - intrs = int(line.split()[1]) - elif OPENBSD: - # Note: the C ext is returning some metrics we are not exposing: - # traps, faults and forks. - ctxsw, intrs, soft_intrs, syscalls, traps, faults, forks = \ - cext.cpu_stats() - return _common.scpustats(ctxsw, intrs, soft_intrs, syscalls) - - -# ===================================================================== -# --- disks -# ===================================================================== - - -def disk_partitions(all=False): - """Return mounted disk partitions as a list of namedtuples. - 'all' argument is ignored, see: - https://github.com/giampaolo/psutil/issues/906 - """ - retlist = [] - partitions = cext.disk_partitions() - for partition in partitions: - device, mountpoint, fstype, opts = partition - ntuple = _common.sdiskpart(device, mountpoint, fstype, opts) - retlist.append(ntuple) - return retlist - - -disk_usage = _psposix.disk_usage -disk_io_counters = cext.disk_io_counters - - -# ===================================================================== -# --- network -# ===================================================================== - - -net_io_counters = cext.net_io_counters -net_if_addrs = cext_posix.net_if_addrs - - -def net_if_stats(): - """Get NIC stats (isup, duplex, speed, mtu).""" - names = net_io_counters().keys() - ret = {} - for name in names: - try: - mtu = cext_posix.net_if_mtu(name) - isup = cext_posix.net_if_flags(name) - duplex, speed = cext_posix.net_if_duplex_speed(name) - except OSError as err: - # https://github.com/giampaolo/psutil/issues/1279 - if err.errno != errno.ENODEV: - raise - else: - if hasattr(_common, 'NicDuplex'): - duplex = _common.NicDuplex(duplex) - ret[name] = _common.snicstats(isup, duplex, speed, mtu) - return ret - - -def net_connections(kind): - """System-wide network connections.""" - if OPENBSD: - ret = [] - for pid in pids(): - try: - cons = Process(pid).connections(kind) - except (NoSuchProcess, ZombieProcess): - continue - else: - for conn in cons: - conn = list(conn) - conn.append(pid) - ret.append(_common.sconn(*conn)) - return ret - - if kind not in _common.conn_tmap: - raise ValueError("invalid %r kind argument; choose between %s" - % (kind, ', '.join([repr(x) for x in conn_tmap]))) - families, types = conn_tmap[kind] - ret = set() - if NETBSD: - rawlist = cext.net_connections(-1) - else: - rawlist = cext.net_connections() - for item in rawlist: - fd, fam, type, laddr, raddr, status, pid = item - # TODO: apply filter at C level - if fam in families and type in types: - nt = conn_to_ntuple(fd, fam, type, laddr, raddr, status, - TCP_STATUSES, pid) - ret.add(nt) - return list(ret) - - -# ===================================================================== -# --- sensors -# ===================================================================== - - -if FREEBSD: - - def sensors_battery(): - """Return battery info.""" - try: - percent, minsleft, power_plugged = cext.sensors_battery() - except NotImplementedError: - # See: https://github.com/giampaolo/psutil/issues/1074 - return None - power_plugged = power_plugged == 1 - if power_plugged: - secsleft = _common.POWER_TIME_UNLIMITED - elif minsleft == -1: - secsleft = _common.POWER_TIME_UNKNOWN - else: - secsleft = minsleft * 60 - return _common.sbattery(percent, secsleft, power_plugged) - - def sensors_temperatures(): - "Return CPU cores temperatures if available, else an empty dict." - ret = defaultdict(list) - num_cpus = cpu_count_logical() - for cpu in range(num_cpus): - try: - current, high = cext.sensors_cpu_temperature(cpu) - if high <= 0: - high = None - name = "Core %s" % cpu - ret["coretemp"].append( - _common.shwtemp(name, current, high, high)) - except NotImplementedError: - pass - - return ret - - def cpu_freq(): - """Return frequency metrics for CPUs. As of Dec 2018 only - CPU 0 appears to be supported by FreeBSD and all other cores - match the frequency of CPU 0. - """ - ret = [] - num_cpus = cpu_count_logical() - for cpu in range(num_cpus): - try: - current, available_freq = cext.cpu_frequency(cpu) - except NotImplementedError: - continue - if available_freq: - try: - min_freq = int(available_freq.split(" ")[-1].split("/")[0]) - except(IndexError, ValueError): - min_freq = None - try: - max_freq = int(available_freq.split(" ")[0].split("/")[0]) - except(IndexError, ValueError): - max_freq = None - ret.append(_common.scpufreq(current, min_freq, max_freq)) - return ret - - -# ===================================================================== -# --- other system functions -# ===================================================================== - - -def boot_time(): - """The system boot time expressed in seconds since the epoch.""" - return cext.boot_time() - - -def users(): - """Return currently connected users as a list of namedtuples.""" - retlist = [] - rawlist = cext.users() - for item in rawlist: - user, tty, hostname, tstamp, pid = item - if pid == -1: - assert OPENBSD - pid = None - if tty == '~': - continue # reboot or shutdown - nt = _common.suser(user, tty or None, hostname, tstamp, pid) - retlist.append(nt) - return retlist - - -# ===================================================================== -# --- processes -# ===================================================================== - - -@memoize -def _pid_0_exists(): - try: - Process(0).name() - except NoSuchProcess: - return False - except AccessDenied: - return True - else: - return True - - -def pids(): - """Returns a list of PIDs currently running on the system.""" - ret = cext.pids() - if OPENBSD and (0 not in ret) and _pid_0_exists(): - # On OpenBSD the kernel does not return PID 0 (neither does - # ps) but it's actually querable (Process(0) will succeed). - ret.insert(0, 0) - return ret - - -if OPENBSD or NETBSD: - def pid_exists(pid): - """Return True if pid exists.""" - exists = _psposix.pid_exists(pid) - if not exists: - # We do this because _psposix.pid_exists() lies in case of - # zombie processes. - return pid in pids() - else: - return True -else: - pid_exists = _psposix.pid_exists - - -def is_zombie(pid): - try: - st = cext.proc_oneshot_info(pid)[kinfo_proc_map['status']] - return st == cext.SZOMB - except Exception: - return False - - -def wrap_exceptions(fun): - """Decorator which translates bare OSError exceptions into - NoSuchProcess and AccessDenied. - """ - @functools.wraps(fun) - def wrapper(self, *args, **kwargs): - try: - return fun(self, *args, **kwargs) - except ProcessLookupError: - if not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._name) - else: - raise ZombieProcess(self.pid, self._name, self._ppid) - except PermissionError: - raise AccessDenied(self.pid, self._name) - except OSError: - if self.pid == 0: - if 0 in pids(): - raise AccessDenied(self.pid, self._name) - else: - raise - raise - return wrapper - - -@contextlib.contextmanager -def wrap_exceptions_procfs(inst): - """Same as above, for routines relying on reading /proc fs.""" - try: - yield - except (ProcessLookupError, FileNotFoundError): - # ENOENT (no such file or directory) gets raised on open(). - # ESRCH (no such process) can get raised on read() if - # process is gone in meantime. - if not pid_exists(inst.pid): - raise NoSuchProcess(inst.pid, inst._name) - else: - raise ZombieProcess(inst.pid, inst._name, inst._ppid) - except PermissionError: - raise AccessDenied(inst.pid, inst._name) - - -class Process(object): - """Wrapper class around underlying C implementation.""" - - __slots__ = ["pid", "_name", "_ppid", "_cache"] - - def __init__(self, pid): - self.pid = pid - self._name = None - self._ppid = None - - def _assert_alive(self): - """Raise NSP if the process disappeared on us.""" - # For those C function who do not raise NSP, possibly returning - # incorrect or incomplete result. - cext.proc_name(self.pid) - - @wrap_exceptions - @memoize_when_activated - def oneshot(self): - """Retrieves multiple process info in one shot as a raw tuple.""" - ret = cext.proc_oneshot_info(self.pid) - assert len(ret) == len(kinfo_proc_map) - return ret - - def oneshot_enter(self): - self.oneshot.cache_activate(self) - - def oneshot_exit(self): - self.oneshot.cache_deactivate(self) - - @wrap_exceptions - def name(self): - name = self.oneshot()[kinfo_proc_map['name']] - return name if name is not None else cext.proc_name(self.pid) - - @wrap_exceptions - def exe(self): - if FREEBSD: - if self.pid == 0: - return '' # else NSP - return cext.proc_exe(self.pid) - elif NETBSD: - if self.pid == 0: - # /proc/0 dir exists but /proc/0/exe doesn't - return "" - with wrap_exceptions_procfs(self): - return os.readlink("/proc/%s/exe" % self.pid) - else: - # OpenBSD: exe cannot be determined; references: - # https://chromium.googlesource.com/chromium/src/base/+/ - # master/base_paths_posix.cc - # We try our best guess by using which against the first - # cmdline arg (may return None). - cmdline = self.cmdline() - if cmdline: - return which(cmdline[0]) or "" - else: - return "" - - @wrap_exceptions - def cmdline(self): - if OPENBSD and self.pid == 0: - return [] # ...else it crashes - elif NETBSD: - # XXX - most of the times the underlying sysctl() call on Net - # and Open BSD returns a truncated string. - # Also /proc/pid/cmdline behaves the same so it looks - # like this is a kernel bug. - try: - return cext.proc_cmdline(self.pid) - except OSError as err: - if err.errno == errno.EINVAL: - if is_zombie(self.pid): - raise ZombieProcess(self.pid, self._name, self._ppid) - elif not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._name, self._ppid) - else: - # XXX: this happens with unicode tests. It means the C - # routine is unable to decode invalid unicode chars. - return [] - else: - raise - else: - return cext.proc_cmdline(self.pid) - - @wrap_exceptions - def terminal(self): - tty_nr = self.oneshot()[kinfo_proc_map['ttynr']] - tmap = _psposix.get_terminal_map() - try: - return tmap[tty_nr] - except KeyError: - return None - - @wrap_exceptions - def ppid(self): - self._ppid = self.oneshot()[kinfo_proc_map['ppid']] - return self._ppid - - @wrap_exceptions - def uids(self): - rawtuple = self.oneshot() - return _common.puids( - rawtuple[kinfo_proc_map['real_uid']], - rawtuple[kinfo_proc_map['effective_uid']], - rawtuple[kinfo_proc_map['saved_uid']]) - - @wrap_exceptions - def gids(self): - rawtuple = self.oneshot() - return _common.pgids( - rawtuple[kinfo_proc_map['real_gid']], - rawtuple[kinfo_proc_map['effective_gid']], - rawtuple[kinfo_proc_map['saved_gid']]) - - @wrap_exceptions - def cpu_times(self): - rawtuple = self.oneshot() - return _common.pcputimes( - rawtuple[kinfo_proc_map['user_time']], - rawtuple[kinfo_proc_map['sys_time']], - rawtuple[kinfo_proc_map['ch_user_time']], - rawtuple[kinfo_proc_map['ch_sys_time']]) - - if FREEBSD: - @wrap_exceptions - def cpu_num(self): - return self.oneshot()[kinfo_proc_map['cpunum']] - - @wrap_exceptions - def memory_info(self): - rawtuple = self.oneshot() - return pmem( - rawtuple[kinfo_proc_map['rss']], - rawtuple[kinfo_proc_map['vms']], - rawtuple[kinfo_proc_map['memtext']], - rawtuple[kinfo_proc_map['memdata']], - rawtuple[kinfo_proc_map['memstack']]) - - memory_full_info = memory_info - - @wrap_exceptions - def create_time(self): - return self.oneshot()[kinfo_proc_map['create_time']] - - @wrap_exceptions - def num_threads(self): - if HAS_PROC_NUM_THREADS: - # FreeBSD - return cext.proc_num_threads(self.pid) - else: - return len(self.threads()) - - @wrap_exceptions - def num_ctx_switches(self): - rawtuple = self.oneshot() - return _common.pctxsw( - rawtuple[kinfo_proc_map['ctx_switches_vol']], - rawtuple[kinfo_proc_map['ctx_switches_unvol']]) - - @wrap_exceptions - def threads(self): - # Note: on OpenSBD this (/dev/mem) requires root access. - rawlist = cext.proc_threads(self.pid) - retlist = [] - for thread_id, utime, stime in rawlist: - ntuple = _common.pthread(thread_id, utime, stime) - retlist.append(ntuple) - if OPENBSD: - self._assert_alive() - return retlist - - @wrap_exceptions - def connections(self, kind='inet'): - if kind not in conn_tmap: - raise ValueError("invalid %r kind argument; choose between %s" - % (kind, ', '.join([repr(x) for x in conn_tmap]))) - - if NETBSD: - families, types = conn_tmap[kind] - ret = [] - rawlist = cext.net_connections(self.pid) - for item in rawlist: - fd, fam, type, laddr, raddr, status, pid = item - assert pid == self.pid - if fam in families and type in types: - nt = conn_to_ntuple(fd, fam, type, laddr, raddr, status, - TCP_STATUSES) - ret.append(nt) - self._assert_alive() - return list(ret) - - families, types = conn_tmap[kind] - rawlist = cext.proc_connections(self.pid, families, types) - ret = [] - for item in rawlist: - fd, fam, type, laddr, raddr, status = item - nt = conn_to_ntuple(fd, fam, type, laddr, raddr, status, - TCP_STATUSES) - ret.append(nt) - - if OPENBSD: - self._assert_alive() - - return ret - - @wrap_exceptions - def wait(self, timeout=None): - return _psposix.wait_pid(self.pid, timeout, self._name) - - @wrap_exceptions - def nice_get(self): - return cext_posix.getpriority(self.pid) - - @wrap_exceptions - def nice_set(self, value): - return cext_posix.setpriority(self.pid, value) - - @wrap_exceptions - def status(self): - code = self.oneshot()[kinfo_proc_map['status']] - # XXX is '?' legit? (we're not supposed to return it anyway) - return PROC_STATUSES.get(code, '?') - - @wrap_exceptions - def io_counters(self): - rawtuple = self.oneshot() - return _common.pio( - rawtuple[kinfo_proc_map['read_io_count']], - rawtuple[kinfo_proc_map['write_io_count']], - -1, - -1) - - @wrap_exceptions - def cwd(self): - """Return process current working directory.""" - # sometimes we get an empty string, in which case we turn - # it into None - if OPENBSD and self.pid == 0: - return None # ...else it would raise EINVAL - elif NETBSD or HAS_PROC_OPEN_FILES: - # FreeBSD < 8 does not support functions based on - # kinfo_getfile() and kinfo_getvmmap() - return cext.proc_cwd(self.pid) or None - else: - raise NotImplementedError( - "supported only starting from FreeBSD 8" if - FREEBSD else "") - - 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') - - def _not_implemented(self): - raise NotImplementedError - - # FreeBSD < 8 does not support functions based on kinfo_getfile() - # and kinfo_getvmmap() - if HAS_PROC_OPEN_FILES: - @wrap_exceptions - def open_files(self): - """Return files opened by process as a list of namedtuples.""" - rawlist = cext.proc_open_files(self.pid) - return [_common.popenfile(path, fd) for path, fd in rawlist] - else: - open_files = _not_implemented - - # FreeBSD < 8 does not support functions based on kinfo_getfile() - # and kinfo_getvmmap() - if HAS_PROC_NUM_FDS: - @wrap_exceptions - def num_fds(self): - """Return the number of file descriptors opened by this process.""" - ret = cext.proc_num_fds(self.pid) - if NETBSD: - self._assert_alive() - return ret - else: - num_fds = _not_implemented - - # --- FreeBSD only APIs - - if FREEBSD: - - @wrap_exceptions - def cpu_affinity_get(self): - return cext.proc_cpu_affinity_get(self.pid) - - @wrap_exceptions - def cpu_affinity_set(self, cpus): - # Pre-emptively check if CPUs are valid because the C - # function has a weird behavior in case of invalid CPUs, - # see: https://github.com/giampaolo/psutil/issues/586 - allcpus = tuple(range(len(per_cpu_times()))) - for cpu in cpus: - if cpu not in allcpus: - raise ValueError("invalid CPU #%i (choose between %s)" - % (cpu, allcpus)) - try: - cext.proc_cpu_affinity_set(self.pid, cpus) - except OSError as err: - # 'man cpuset_setaffinity' about EDEADLK: - # <<the call would leave a thread without a valid CPU to run - # on because the set does not overlap with the thread's - # anonymous mask>> - if err.errno in (errno.EINVAL, errno.EDEADLK): - for cpu in cpus: - if cpu not in allcpus: - raise ValueError( - "invalid CPU #%i (choose between %s)" % ( - cpu, allcpus)) - raise - - @wrap_exceptions - def memory_maps(self): - return cext.proc_memory_maps(self.pid)
