diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2015-11-09 13:40:09 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2015-11-09 13:40:09 +0100 |
commit | ba5d61d047c930ead6aedbd4d5ab7ab7990684f5 (patch) | |
tree | bf8fd6e3a69e998e6fddfaffafd8c05958205e30 | |
parent | 4cb337336736e982d14b2d56c0a4411b747a7d6e (diff) | |
download | psutil-ba5d61d047c930ead6aedbd4d5ab7ab7990684f5.tar.gz |
#615: fix process status()
-rw-r--r-- | psutil/__init__.py | 10 | ||||
-rw-r--r-- | psutil/_psbsd.py | 57 | ||||
-rw-r--r-- | psutil/_psutil_openbsd.c | 23 | ||||
-rw-r--r-- | test/test_psutil.py | 6 |
4 files changed, 77 insertions, 19 deletions
diff --git a/psutil/__init__.py b/psutil/__init__.py index 47ef5cfd..d88b844a 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -1029,8 +1029,14 @@ class Process(object): os.kill(self.pid, sig) except OSError as err: if err.errno == errno.ESRCH: - self._gone = True - raise NoSuchProcess(self.pid, self._name) + if (sys.platform.startswith("openbsd") and \ + pid_exists(self.pid)): + # We do this because os.kill() lies in case of + # zombie processes. + raise ZombieProcess(self.pid, self._name, self._ppid) + else: + self._gone = True + raise NoSuchProcess(self.pid, self._name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._name) raise diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 60fcdd48..54e33289 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -29,15 +29,37 @@ __extra__all__ = [] FREEBSD = sys.platform.startswith("freebsd") OPENBSD = sys.platform.startswith("openbsd") -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, -} +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: + 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, + # 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, + } TCP_STATUSES = { cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, @@ -249,8 +271,20 @@ def net_if_stats(): return ret +if OPENBSD: + def pid_exists(pid): + 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 + + pids = cext.pids -pid_exists = _psposix.pid_exists disk_usage = _psposix.disk_usage net_io_counters = cext.net_io_counters disk_io_counters = cext.disk_io_counters @@ -271,7 +305,8 @@ def wrap_exceptions(fun): ZombieProcess is None): raise if err.errno == errno.ESRCH: - if not pid_exists(self.pid): + # if not pid_exists(self.pid): + if self.pid not in pids(): raise NoSuchProcess(self.pid, self._name) else: raise ZombieProcess(self.pid, self._name, self._ppid) diff --git a/psutil/_psutil_openbsd.c b/psutil/_psutil_openbsd.c index d7ad4c13..1c3c2169 100644 --- a/psutil/_psutil_openbsd.c +++ b/psutil/_psutil_openbsd.c @@ -1850,14 +1850,25 @@ void init_psutil_bsd(void) #endif PyModule_AddIntConstant(module, "version", PSUTIL_VERSION); // process status constants - PyModule_AddIntConstant(module, "SSTOP", SSTOP); - PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); - PyModule_AddIntConstant(module, "SRUN", SRUN); + +#ifdef __FreeBSD__ PyModule_AddIntConstant(module, "SIDL", SIDL); - PyModule_AddIntConstant(module, "SWAIT", -1); - PyModule_AddIntConstant(module, "SLOCK", -1); + PyModule_AddIntConstant(module, "SRUN", SRUN); + PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); + PyModule_AddIntConstant(module, "SSTOP", SSTOP); PyModule_AddIntConstant(module, "SZOMB", SZOMB); - PyModule_AddIntConstant(module, "SRUN", SONPROC); + PyModule_AddIntConstant(module, "SWAIT", SWAIT); + PyModule_AddIntConstant(module, "SLOCK", SLOCK); +#elif __OpenBSD__ + PyModule_AddIntConstant(module, "SIDL", SIDL); + PyModule_AddIntConstant(module, "SRUN", SRUN); + PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); + PyModule_AddIntConstant(module, "SSTOP", SSTOP); + PyModule_AddIntConstant(module, "SZOMB", SZOMB); // unused + PyModule_AddIntConstant(module, "SDEAD", SDEAD); + PyModule_AddIntConstant(module, "SONPROC", SONPROC); +#endif + // connection status constants PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED); PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING); diff --git a/test/test_psutil.py b/test/test_psutil.py index 0e4fe2da..9a3a963c 100644 --- a/test/test_psutil.py +++ b/test/test_psutil.py @@ -1627,6 +1627,12 @@ class TestProcess(unittest.TestCase): def test_threads_2(self): p = psutil.Process() + if OPENBSD: + try: + p.threads() + except psutil.AccessDenied: + raise unittest.SkipTest( + "on OpenBSD this requires root access") self.assertAlmostEqual(p.cpu_times().user, p.threads()[0].user_time, delta=0.1) self.assertAlmostEqual(p.cpu_times().system, |