summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-01-08 11:51:26 +0000
committerGiampaolo Rodola <g.rodola@gmail.com>2016-01-08 11:51:26 +0000
commite44d5e428c5cd6c31e080dd0830300f1c069b0ca (patch)
tree38354c648a4c90dfce87f40a606c0e08d23860cb
parentbc6cf436e2c253c863380839af32289b67640572 (diff)
downloadpsutil-e44d5e428c5cd6c31e080dd0830300f1c069b0ca.tar.gz
#557 (NetBSD): various refactorings
-rw-r--r--docs/index.rst5
-rw-r--r--psutil/__init__.py9
-rw-r--r--psutil/_psbsd.py80
-rw-r--r--psutil/_psutil_bsd.c2
-rw-r--r--psutil/arch/bsd/netbsd.c49
-rw-r--r--test/test_psutil.py4
6 files changed, 59 insertions, 90 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 3a5f8e62..fc43d70a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -8,6 +8,7 @@
Old 1.2.1 documentation is still available
`here <https://code.google.com/p/psutil/wiki/Documentation>`__.
.. versionchanged:: 3.3.0 added support for OpenBSD
+.. versionchanged:: 3.4.0 added support for NetBSD
psutil documentation
====================
@@ -206,7 +207,7 @@ Memory
* **sout**: the number of bytes the system has swapped out from disk
(cumulative)
- **sin** and **sout** on Windows are meaningless and are always set to ``0``.
+ **sin** and **sout** on Windows, OpenBSD and NetBSD are always set to ``0``.
See `examples/meminfo.py <https://github.com/giampaolo/psutil/blob/master/examples/meminfo.py>`__
script providing an example on how to convert bytes in a human readable form.
@@ -1043,7 +1044,7 @@ Process class
...]
>>>
- Availability: All platforms except OpenBSD.
+ Availability: All platforms except OpenBSD and NetBSD.
.. method:: children(recursive=False)
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 2ab1b7f2..e5f06a87 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -123,8 +123,9 @@ elif sys.platform.startswith("win32"):
elif sys.platform.startswith("darwin"):
from . import _psosx as _psplatform
-elif sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd") \
- or sys.platform.startswith("netbsd"):
+elif sys.platform.startswith("freebsd") or \
+ sys.platform.startswith("openbsd") or \
+ sys.platform.startswith("netbsd"):
from . import _psbsd as _psplatform
elif sys.platform.startswith("sunos"):
@@ -969,7 +970,9 @@ class Process(object):
except ZeroDivisionError:
return 0.0
- if not _OPENBSD:
+ if hasattr(_psplatform.Process, "memory_maps"):
+ # Available everywhere except OpenBSD and NetBSD.
+
def memory_maps(self, grouped=True):
"""Return process' mapped memory regions as a list of namedtuples
whose fields are variable depending on the platform.
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index 3304cece..032b87c0 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -521,66 +521,67 @@ class Process(object):
rc, wc, rb, wb = cext.proc_io_counters(self.pid)
return _common.pio(rc, wc, rb, wb)
+ @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:
+ try:
+ 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()
+ 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 hasattr(cext, '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
- @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:
- try:
- 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
- else:
- return cext.proc_cwd(self.pid) or None
-
- @wrap_exceptions
- def memory_maps(self):
- if FREEBSD:
- return cext.proc_memory_maps(self.pid)
- else:
- # TODO
- raise NotImplementedError
-
+ # FreeBSD < 8 does not support functions based on kinfo_getfile()
+ # and kinfo_getvmmap()
+ if hasattr(cext, 'proc_num_fds'):
@wrap_exceptions
def num_fds(self):
"""Return the number of file descriptors opened by this process."""
return cext.proc_num_fds(self.pid)
-
else:
- def _not_implemented(self):
- raise NotImplementedError("supported only starting from FreeBSD 8")
-
- open_files = _not_implemented
- proc_cwd = _not_implemented
- memory_maps = _not_implemented
num_fds = _not_implemented
+ # --- FreeBSD only APIs
+
if FREEBSD:
+
@wrap_exceptions
def cpu_affinity_get(self):
return cext.proc_cpu_affinity_get(self.pid)
@@ -609,3 +610,6 @@ class Process(object):
"invalid CPU #%i (choose between %s)" % (
cpu, allcpus))
raise
+
+ def memory_maps(self):
+ return cext.proc_memory_maps(self.pid)
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index 888cf7b7..a621afc2 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -9,7 +9,7 @@
* OpenBSD references:
* - OpenBSD source code: http://anoncvs.spacehopper.org/openbsd-src/
*
- * OpenBSD: missing compared to FreeBSD implementation:
+ * OpenBSD / NetBSD: missing APIs compared to FreeBSD implementation:
* - psutil.net_connections()
* - psutil.Process.get/set_cpu_affinity() (not supported natively)
* - psutil.Process.memory_maps()
diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c
index 5491c0fe..48373c72 100644
--- a/psutil/arch/bsd/netbsd.c
+++ b/psutil/arch/bsd/netbsd.c
@@ -461,7 +461,8 @@ psutil_swap_mem(PyObject *self, PyObject *args) {
return Py_BuildValue("(iiiii)", 0, 0, 0, 0, 0);
}
- if ((swdev = calloc(nswap, sizeof(*swdev))) == NULL) {
+ swdev = calloc(nswap, sizeof(*swdev));
+ if (swdev == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
@@ -511,40 +512,6 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) {
}
-// see sys/kern/kern_sysctl.c lines 1100 and
-// usr.bin/fstat/fstat.c print_inet_details()
-static char *
-psutil_convert_ipv4(int family, uint32_t addr[4]) {
- struct in_addr a;
- memcpy(&a, addr, sizeof(a));
- return inet_ntoa(a);
-}
-
-
-static char *
-psutil_inet6_addrstr(struct in6_addr *p) {
- struct sockaddr_in6 sin6;
- static char hbuf[NI_MAXHOST];
- const int niflags = NI_NUMERICHOST;
-
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_addr = *p;
- if (IN6_IS_ADDR_LINKLOCAL(p) &&
- *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) {
- sin6.sin6_scope_id =
- ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
- sin6.sin6_addr.s6_addr[2] = sin6.sin6_addr.s6_addr[3] = 0;
- }
-
- if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
- hbuf, sizeof(hbuf), NULL, 0, niflags))
- return "invalid";
-
- return hbuf;
-}
-
PyObject *
psutil_per_cpu_times(PyObject *self, PyObject *args) {
static int maxcpus;
@@ -553,13 +520,11 @@ psutil_per_cpu_times(PyObject *self, PyObject *args) {
size_t len;
size_t size;
int i;
- PyObject *py_retlist = PyList_New(0);
PyObject *py_cputime = NULL;
+ PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL)
return NULL;
-
-
// retrieve the number of cpus
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
@@ -610,12 +575,11 @@ psutil_disk_io_counters(PyObject *self, PyObject *args) {
int i, dk_ndrive, mib[3];
size_t len;
struct io_sysctl *stats;
-
- PyObject *py_retdict = PyDict_New();
PyObject *py_disk_info = NULL;
+ PyObject *py_retdict = PyDict_New();
+
if (py_retdict == NULL)
return NULL;
-
mib[0] = CTL_HW;
mib[1] = HW_IOSTATS;
mib[2] = sizeof(struct io_sysctl);
@@ -629,12 +593,10 @@ psutil_disk_io_counters(PyObject *self, PyObject *args) {
stats = malloc(len);
if (stats == NULL) {
- warn("can't malloc");
PyErr_NoMemory();
goto error;
}
if (sysctl(mib, 2, stats, &len, NULL, 0) < 0 ) {
- warn("could not read HW_IOSTATS");
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
@@ -667,4 +629,3 @@ error:
free(stats);
return NULL;
}
-
diff --git a/test/test_psutil.py b/test/test_psutil.py
index fba71d20..d1039fc1 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -1670,7 +1670,7 @@ class TestProcess(unittest.TestCase):
# def test_memory_info_ex(self):
# # tested later in fetch all test suite
- @unittest.skipIf(OPENBSD, "not available on OpenBSD")
+ @unittest.skipIf(OPENBSD or NETBSD, "not available on this platform")
def test_memory_maps(self):
p = psutil.Process()
maps = p.memory_maps()
@@ -3122,7 +3122,7 @@ class TestExampleScripts(unittest.TestCase):
def test_ifconfig(self):
self.assert_stdout('ifconfig.py')
- @unittest.skipIf(OPENBSD, "OpenBSD does not support memory maps")
+ @unittest.skipIf(OPENBSD or NETBSD, "memory maps not supported")
def test_pmap(self):
self.assert_stdout('pmap.py', args=str(os.getpid()))