diff options
| author | Giampaolo Rodola <g.rodola@gmail.com> | 2016-01-11 21:48:54 +0000 |
|---|---|---|
| committer | Giampaolo Rodola <g.rodola@gmail.com> | 2016-01-11 21:48:54 +0000 |
| commit | 337c6be1cc89a94b42c411317870f72579ce1202 (patch) | |
| tree | 4bf5a761b2fe5ebce81ad4d916baa48c19d772fc | |
| parent | 4bd6bff03f90fef58cd3cd15ef3c7ca655fdc33b (diff) | |
| download | psutil-337c6be1cc89a94b42c411317870f72579ce1202.tar.gz | |
#557 / netbsd: use /proc fs to determine proc exe (see https://github.com/giampaolo/psutil/pull/557#issuecomment-171912820)
| -rw-r--r-- | psutil/_psbsd.py | 57 | ||||
| -rw-r--r-- | psutil/arch/bsd/netbsd.c | 5 |
2 files changed, 42 insertions, 20 deletions
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 47c700e6..f20a80b7 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -2,8 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""FreeBSD and OpenBSD platforms implementation.""" +"""FreeBSD, OpenBSD and NetBSD platforms implementation.""" +import contextlib import errno import functools import os @@ -70,11 +71,9 @@ elif NETBSD: cext.SSTOP: _common.STATUS_STOPPED, cext.SZOMB: _common.STATUS_ZOMBIE, cext.SDEAD: _common.STATUS_DEAD, + cext.SSUSPENDED: _common.STATUS_SUSPENDED, # unique to NetBSD } -if NETBSD: - PROC_STATUSES[cext.SSUSPENDED] = _common.STATUS_SUSPENDED - TCP_STATUSES = { cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT, @@ -334,6 +333,27 @@ def wrap_exceptions(fun): return wrapper +@contextlib.contextmanager +def wrap_exceptions_procfs(inst): + try: + yield + except EnvironmentError as err: + # support for private module import + if NoSuchProcess is None or AccessDenied is None: + raise + # 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 err.errno in (errno.ENOENT, errno.ESRCH): + if not pid_exists(inst.pid): + raise NoSuchProcess(inst.pid, inst._name) + else: + raise ZombieProcess(inst.pid, inst._name, inst._ppid) + if err.errno in (errno.EPERM, errno.EACCES): + raise AccessDenied(inst.pid, inst._name) + raise + + class Process(object): """Wrapper class around underlying C implementation.""" @@ -350,10 +370,16 @@ class Process(object): @wrap_exceptions def exe(self): - if FREEBSD or NETBSD: + if FREEBSD: 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: - # exe cannot be determined on OpenBSD; references: + # 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 @@ -366,13 +392,13 @@ class Process(object): @wrap_exceptions def cmdline(self): - # 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. if OPENBSD and self.pid == 0: return None # ...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: @@ -535,17 +561,8 @@ class Process(object): if OPENBSD and self.pid == 0: return None # ...else it would raise EINVAL elif NETBSD: - try: + with wrap_exceptions_procfs(self): return os.readlink("/proc/%s/cwd" % self.pid) - except OSError as err: - if err.errno == errno.ENOENT: - if not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._name) - else: - raise ZombieProcess( - self.pid, self._name, self._ppid) - else: - raise elif hasattr(cext, 'proc_open_files'): # FreeBSD < 8 does not support functions based on # kinfo_getfile() and kinfo_getvmmap() diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index f3cfd53b..4c300361 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -147,6 +147,11 @@ psutil_pid_exists(pid_t pid) { } } + +// XXX: This is no longer used as per +// https://github.com/giampaolo/psutil/pull/557#issuecomment-171912820 +// Current implementation uses /proc instead. +// Left here just in case. PyObject * psutil_proc_exe(PyObject *self, PyObject *args) { #if __NetBSD_Version__ >= 799000000 |
