diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2016-01-13 23:50:30 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2016-01-13 23:50:30 +0100 |
commit | 89dbd1d1e5b17c03f1252eb734d0c1cd5b445a48 (patch) | |
tree | bacce7b30ec4ebb5ab5c715ceff714dacea2e512 | |
parent | 94c37c17fa1d59e04edb2f5f79ec6a5814cffded (diff) | |
download | psutil-89dbd1d1e5b17c03f1252eb734d0c1cd5b445a48.tar.gz |
#734: fix unicode issues on FreeBSD
-rw-r--r-- | psutil/_common.py | 4 | ||||
-rw-r--r-- | psutil/_psbsd.py | 11 | ||||
-rw-r--r-- | psutil/_psosx.py | 8 | ||||
-rw-r--r-- | psutil/_psutil_bsd.c | 17 | ||||
-rw-r--r-- | psutil/arch/bsd/freebsd.c | 20 | ||||
-rw-r--r-- | test/test_psutil.py | 17 |
6 files changed, 49 insertions, 28 deletions
diff --git a/psutil/_common.py b/psutil/_common.py index 3ff1cb88..c174fdef 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -193,6 +193,10 @@ def socktype_to_enum(num): return num +def get_encoding_errors_handler(): + return sys.modules['psutil'].ENCODING_ERRORS_HANDLER + + # --- Process.connections() 'kind' parameter mapping conn_tmap = { diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index f20a80b7..5b79ea23 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -17,12 +17,12 @@ from . import _psposix from . import _psutil_bsd as cext from . import _psutil_posix as cext_posix from ._common import conn_tmap +from ._common import get_encoding_errors_handler from ._common import sockfam_to_enum from ._common import socktype_to_enum from ._common import usage_percent from ._compat import which - __extra__all__ = [] # --- constants @@ -357,21 +357,22 @@ def wrap_exceptions_procfs(inst): class Process(object): """Wrapper class around underlying C implementation.""" - __slots__ = ["pid", "_name", "_ppid"] + __slots__ = ["pid", "_name", "_ppid", "_encoding_errs"] def __init__(self, pid): self.pid = pid self._name = None self._ppid = None + self._encoding_errs = get_encoding_errors_handler() @wrap_exceptions def name(self): - return cext.proc_name(self.pid) + return cext.proc_name(self.pid, self._encoding_errs) @wrap_exceptions def exe(self): if FREEBSD: - return cext.proc_exe(self.pid) + return cext.proc_exe(self.pid, self._encoding_errs) elif NETBSD: if self.pid == 0: # /proc/0 dir exists but /proc/0/exe doesn't @@ -566,7 +567,7 @@ class Process(object): 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 + return cext.proc_cwd(self.pid, self._encoding_errs) or None else: raise NotImplementedError( "supported only starting from FreeBSD 8" if diff --git a/psutil/_psosx.py b/psutil/_psosx.py index 26f1337f..ff6796e0 100644 --- a/psutil/_psosx.py +++ b/psutil/_psosx.py @@ -7,7 +7,6 @@ import errno import functools import os -import sys from collections import namedtuple from . import _common @@ -15,6 +14,7 @@ from . import _psposix from . import _psutil_osx as cext from . import _psutil_posix as cext_posix from ._common import conn_tmap +from ._common import get_encoding_errors_handler from ._common import isfile_strict from ._common import sockfam_to_enum from ._common import socktype_to_enum @@ -74,12 +74,6 @@ AccessDenied = None TimeoutExpired = None -# --- utils - -def get_encoding_errors_handler(): - return sys.modules['psutil'].ENCODING_ERRORS_HANDLER - - # --- functions def virtual_memory(): diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 5d22d881..1fdb4c00 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -192,14 +192,25 @@ static PyObject * psutil_proc_name(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) + char str[1000]; + const char *encoding_errs; + + if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; + #ifdef __FreeBSD__ - return Py_BuildValue("s", kp.ki_comm); + sprintf(str, "%s", kp.ki_comm); #elif defined(__OpenBSD__) || defined(__NetBSD__) - return Py_BuildValue("s", kp.p_comm); + sprintf(str, "%s", kp.p_comm); +#endif + +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_Decode( + str, strlen(str), Py_FileSystemDefaultEncoding, encoding_errs); +#else + return Py_BuildValue("s", str); #endif } diff --git a/psutil/arch/bsd/freebsd.c b/psutil/arch/bsd/freebsd.c index 3b7fc478..4042ffd1 100644 --- a/psutil/arch/bsd/freebsd.c +++ b/psutil/arch/bsd/freebsd.c @@ -317,8 +317,9 @@ psutil_proc_exe(PyObject *self, PyObject *args) { int mib[4]; int ret; size_t size; + const char *encoding_errs; - if (! PyArg_ParseTuple(args, "l", &pid)) + if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs)) return NULL; mib[0] = CTL_KERN; @@ -341,7 +342,15 @@ psutil_proc_exe(PyObject *self, PyObject *args) { else strcpy(pathname, ""); } + +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_Decode( + pathname, strlen(pathname), Py_FileSystemDefaultEncoding, + encoding_errs); +#else return Py_BuildValue("s", pathname); +#endif + } @@ -574,11 +583,12 @@ psutil_proc_cwd(PyObject *self, PyObject *args) { struct kinfo_file *freep = NULL; struct kinfo_file *kif; struct kinfo_proc kipp; + const char *encoding_errs; PyObject *py_path = NULL; int i, cnt; - if (! PyArg_ParseTuple(args, "l", &pid)) + if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs)) goto error; if (psutil_kinfo_proc(pid, &kipp) == -1) goto error; @@ -592,7 +602,13 @@ psutil_proc_cwd(PyObject *self, PyObject *args) { for (i = 0; i < cnt; i++) { kif = &freep[i]; if (kif->kf_fd == KF_FD_TYPE_CWD) { +#if PY_MAJOR_VERSION >= 3 + py_path = PyUnicode_Decode( + kif->kf_path, strlen(kif->kf_path), + Py_FileSystemDefaultEncoding, encoding_errs); +#else py_path = Py_BuildValue("s", kif->kf_path); +#endif if (!py_path) goto error; break; diff --git a/test/test_psutil.py b/test/test_psutil.py index 333015be..c72a8543 100644 --- a/test/test_psutil.py +++ b/test/test_psutil.py @@ -3313,25 +3313,20 @@ class TestNonUnicode(unittest.TestCase): stdout=subprocess.PIPE, stderr=subprocess.STDOUT) p = psutil.Process(subp.pid) - self.assertIsInstance(p.name(), str) self.assertEqual(encode_path(os.path.basename(p.name())), b"\xc0\x80") subp.communicate() self.assertEqual(subp.returncode, 0) def test_proc_cmdline(self): - funny_file = os.path.join(self.temp_directory, b"\xc0\x80") - open(funny_file, "wb").close() - self.addCleanup(safe_remove, funny_file) - cmd = [self.test_executable] - if WINDOWS: - cmd.extend(["/K", "type \xc0\x80"]) - subp = get_test_subprocess(cmd=cmd, + funny_executable = os.path.join(self.temp_directory, b"\xc0\x80") + self.copy_file(self.test_executable, funny_executable) + self.addCleanup(safe_remove, funny_executable) + subp = get_test_subprocess(cmd=[decode_path(funny_executable)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - cwd=decode_path(self.temp_directory)) + stderr=subprocess.STDOUT) p = psutil.Process(subp.pid) - self.assertEqual(p.cmdline()[1:], cmd[1:]) + self.assertEqual(p.cmdline(), [decode_path(funny_executable)]) subp.communicate() self.assertEqual(subp.returncode, 0) |