Skip to content

Commit

Permalink
users() / Linux: make ":0" -> "localhost" host conversion in C instea…
Browse files Browse the repository at this point in the history
…d of python
  • Loading branch information
giampaolo committed Oct 23, 2023
1 parent 1b94083 commit 0c3a1c5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 36 deletions.
9 changes: 1 addition & 8 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -1549,14 +1549,7 @@ def users():
retlist = []
rawlist = cext.users()
for item in rawlist:
user, tty, hostname, tstamp, user_process, pid = item
# note: the underlying C function includes entries about
# system boot, run level and others. We might want
# to use them in the future.
if not user_process:
continue
if hostname in (':0.0', ':0'):
hostname = 'localhost'
user, tty, hostname, tstamp, pid = item
nt = _common.suser(user, tty or None, hostname, tstamp, pid)
retlist.append(nt)
return retlist
Expand Down
17 changes: 8 additions & 9 deletions psutil/arch/linux/users.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <Python.h>
#include <utmp.h>
#include <string.h>

#include "../../_psutil_common.h"

Expand All @@ -18,35 +19,33 @@ psutil_users(PyObject *self, PyObject *args) {
PyObject *py_username = NULL;
PyObject *py_tty = NULL;
PyObject *py_hostname = NULL;
PyObject *py_user_proc = NULL;

if (py_retlist == NULL)
return NULL;
setutent();
while (NULL != (ut = getutent())) {
if (ut->ut_type != USER_PROCESS)
continue;
py_tuple = NULL;
py_user_proc = NULL;
if (ut->ut_type == USER_PROCESS)
py_user_proc = Py_True;
else
py_user_proc = Py_False;
py_username = PyUnicode_DecodeFSDefault(ut->ut_user);
if (! py_username)
goto error;
py_tty = PyUnicode_DecodeFSDefault(ut->ut_line);
if (! py_tty)
goto error;
py_hostname = PyUnicode_DecodeFSDefault(ut->ut_host);
if (strcmp(ut->ut_host, ":0") || strcmp(ut->ut_host, ":0.0"))
py_hostname = PyUnicode_DecodeFSDefault("localhost");
else
py_hostname = PyUnicode_DecodeFSDefault(ut->ut_host);
if (! py_hostname)
goto error;

py_tuple = Py_BuildValue(
"OOOdO" _Py_PARSE_PID,
"OOOd" _Py_PARSE_PID,
py_username, // username
py_tty, // tty
py_hostname, // hostname
(double)ut->ut_tv.tv_sec, // tstamp
py_user_proc, // (bool) user process
ut->ut_pid // process id
);
if (! py_tuple)
Expand Down
24 changes: 5 additions & 19 deletions psutil/tests/test_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -1513,25 +1513,11 @@ def test_boot_time_mocked(self):
psutil._pslinux.boot_time)
assert m.called

def test_users_mocked(self):
# Make sure ':0' and ':0.0' (returned by C ext) are converted
# to 'localhost'.
with mock.patch('psutil._pslinux.cext.users',
return_value=[('giampaolo', 'pts/2', ':0',
1436573184.0, True, 2)]) as m:
self.assertEqual(psutil.users()[0].host, 'localhost')
assert m.called
with mock.patch('psutil._pslinux.cext.users',
return_value=[('giampaolo', 'pts/2', ':0.0',
1436573184.0, True, 2)]) as m:
self.assertEqual(psutil.users()[0].host, 'localhost')
assert m.called
# ...otherwise it should be returned as-is
with mock.patch('psutil._pslinux.cext.users',
return_value=[('giampaolo', 'pts/2', 'foo',
1436573184.0, True, 2)]) as m:
self.assertEqual(psutil.users()[0].host, 'foo')
assert m.called
def test_users(self):
# Make sure the C extension converts ':0' and ':0.0' to
# 'localhost'.
for user in psutil.users():
self.assertNotIn(user.host, (":0", ":0.0"))

def test_procfs_path(self):
tdir = self.get_testfn()
Expand Down

0 comments on commit 0c3a1c5

Please sign in to comment.