diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2015-08-26 08:58:03 -0700 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2015-08-26 08:58:03 -0700 |
commit | b9823dbb3071d902753e713b0c32d027e73a7946 (patch) | |
tree | 1e9c7b9631a43a70866a3b01a9d509f27d6f0956 | |
parent | d592453854a6742c2e9efff25b5203d544853d7a (diff) | |
download | psutil-b9823dbb3071d902753e713b0c32d027e73a7946.tar.gz |
#650: make cmdline() handle unicode on python 2
-rw-r--r-- | docs/index.rst | 4 | ||||
-rw-r--r-- | psutil/_pswindows.py | 15 | ||||
-rw-r--r-- | psutil/arch/windows/process_info.c | 55 | ||||
-rw-r--r-- | test/_windows.py | 6 |
4 files changed, 38 insertions, 42 deletions
diff --git a/docs/index.rst b/docs/index.rst index 69edcead..f7dad748 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -697,6 +697,10 @@ Process class The command line this process has been called with. + *Changed in 3.2.0:* (Windows, Python 2) in case one or more parts of the + cmdline contains non ASCII characters the returned type is a list of + unicode strings. + .. method:: create_time() The process creation time as a floating point number expressed in seconds diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 479cf770..3c86d994 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -315,7 +315,20 @@ class Process(object): @wrap_exceptions def cmdline(self): - return cext.proc_cmdline(self.pid) + ret = cext.proc_cmdline(self.pid) + if PY3: + return ret + else: + # On Python 2, if one or more bits of the cmdline is unicode + # we return a list of unicode strings. + new = [] + for x in ret: + x = py2_stringify(x) + if isinstance(x, unicode): + return ret + else: + new.append(x) + return new def ppid(self): try: diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c index b925b05f..84860413 100644 --- a/psutil/arch/windows/process_info.c +++ b/psutil/arch/windows/process_info.c @@ -217,9 +217,8 @@ psutil_get_arg_list(long pid) { PVOID rtlUserProcParamsAddress; UNICODE_STRING commandLine; WCHAR *commandLineContents = NULL; - PyObject *arg = NULL; - PyObject *arg_from_wchar = NULL; - PyObject *argList = NULL; + PyObject *py_arg = NULL; + PyObject *py_retlist = NULL; hProcess = psutil_handle_from_pid(pid); if (hProcess == NULL) @@ -274,48 +273,27 @@ psutil_get_arg_list(long pid) { // commandLine.Length is in bytes. commandLineContents[(commandLine.Length / sizeof(WCHAR))] = '\0'; - // attempt tp parse the command line using Win32 API, fall back + // attempt to parse the command line using Win32 API, fall back // on string cmdline version otherwise szArglist = CommandLineToArgvW(commandLineContents, &nArgs); - if (NULL == szArglist) { - // failed to parse arglist - // encode as a UTF8 Python string object from WCHAR string - arg_from_wchar = PyUnicode_FromWideChar(commandLineContents, - commandLine.Length / 2); - if (arg_from_wchar == NULL) - goto error; -#if PY_MAJOR_VERSION >= 3 - argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar)); -#else - argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar)); -#endif - if (!argList) - goto error; + if (szArglist == NULL) { + PyErr_SetFromWindowsErr(0); + goto error; } else { // arglist parsed as array of UNICODE_STRING, so convert each to // Python string object and add to arg list - argList = Py_BuildValue("[]"); - if (argList == NULL) + py_retlist = Py_BuildValue("[]"); + if (py_retlist == NULL) goto error; for (i = 0; i < nArgs; i++) { - arg_from_wchar = NULL; - arg = NULL; - arg_from_wchar = PyUnicode_FromWideChar(szArglist[i], - wcslen(szArglist[i])); - if (arg_from_wchar == NULL) - goto error; -#if PY_MAJOR_VERSION >= 3 - arg = PyUnicode_FromObject(arg_from_wchar); -#else - arg = PyUnicode_AsUTF8String(arg_from_wchar); -#endif - if (arg == NULL) + py_arg = PyUnicode_FromWideChar( + szArglist[i], wcslen(szArglist[i])); + if (py_arg == NULL) goto error; - Py_XDECREF(arg_from_wchar); - if (PyList_Append(argList, arg)) + if (PyList_Append(py_retlist, py_arg)) goto error; - Py_XDECREF(arg); + Py_XDECREF(py_arg); } } @@ -323,12 +301,11 @@ psutil_get_arg_list(long pid) { LocalFree(szArglist); free(commandLineContents); CloseHandle(hProcess); - return argList; + return py_retlist; error: - Py_XDECREF(arg); - Py_XDECREF(arg_from_wchar); - Py_XDECREF(argList); + Py_XDECREF(py_arg); + Py_XDECREF(py_retlist); if (hProcess != NULL) CloseHandle(hProcess); if (commandLineContents != NULL) diff --git a/test/_windows.py b/test/_windows.py index 8f2c7a52..70101726 100644 --- a/test/_windows.py +++ b/test/_windows.py @@ -491,8 +491,10 @@ class TestUnicode(unittest.TestCase): shutil.copyfile(sys.executable, self.uexe) subp = get_test_subprocess(cmd=[self.uexe]) p = psutil.Process(subp.pid) - self.assertIsInstance("".join(p.cmdline()), unicode) - self.assertEqual(p.cmdline(), [self.uexe]) + self.assertIsInstance(u("").join(p.cmdline()), unicode) + uexe = self.uexe if PY3 else \ + unicode(self.uexe, sys.getfilesystemencoding()) + self.assertEqual(p.cmdline(), [uexe]) def test_proc_cwd(self): tdir = tempfile.mkdtemp(prefix=u("psutil-รจ-")) |