Closed Ixtalo closed 1 week ago
I think I'm misinterpreting what your saying here but here goes. Are you saying that you expect "127.0.0.1"
instead of "localhost"
? Current doc doesn't say that it will always be an IP, so "localhost"
technically is correct. You can later use gethostbyname
to resolve it to either an IPv4 or IPv6 address:
>>> socket.gethostbyname("localhost")
'127.0.0.1'
Thanks @giampaolo for your response.
Yes, I'm afraid we're talking about different things here.
My issue is not with the name resolution, nor regarding localhost/127.0.0.1. I am concerned about a possibly improper use of “strcmp”.
The described problem here is that with psutil.users
the host-field is always set to "localhost" - even if there is a remote connection (e.g., 192.168.56.1). This is because strcmp(..) || strcmp(...)
is always 1/true.
I think, the intention of the referenced code line (for Linux X Window System check) is:
IF host equals to ":0"/":0.0" THEN "localhost" ELSE host
.
But, IMHO, for this to work as intended you would need (because of the lexicographical comparison done by strcmp
):
if (strcmp(ut->ut_host, ":0") == 0 || strcmp(ut->ut_host, ":0.0") == 0)
A small code example:
// g++ ut_strcmp.cc -o ut_strcmp
// ./ut_strcmp :0
// ./ut_strcmp foobar
#include <iostream>
#include <cstring>
int main(int argn, char** args) {
if (argn < 2) {
std::cerr << "... <arg>" << std::endl;
return 1;
}
const char* host = args[1];
std::cout << "strcmp(host, :0): " << strcmp(host, ":0") << std::endl;
std::cout << "strcmp(host, :0.0): " << strcmp(host, ":0:0") << std::endl;
std::cout << "strcmp(..) || strcmp(...): " << (strcmp(host, ":0") || strcmp(host, ":0:0")) << std::endl;
// incorrect
if (strcmp(host, ":0") || strcmp(host, ":0.0"))
std::cout << "(with no check for == 0, host this is always) " << "localhost" << std::endl;
else
// never happens
std::cout << "this never happens :(" << host << std::endl;
// correct
if (strcmp(host, ":0") == 0 || strcmp(host, ":0.0") == 0)
// host is a standard X Window identifier
std::cout << "(this is correct) " << "localhost" << std::endl;
else
std::cout << host << std::endl;
return 0;
}
$ g++ ut_strcmp.cc -o ut_strcmp && ./ut_strcmp :0
strcmp(host, :0): 0
strcmp(host, :0.0): -58
strcmp(..) || strcmp(...): 1
with no check for == 0, host this is always: localhost
host: localhost
$ g++ ut_strcmp.cc -o ut_strcmp && ./ut_strcmp 192.168.56.1
strcmp(host, :0): 44
strcmp(host, :0.0): 44
strcmp(..) || strcmp(...): 1
with no check for == 0, host this is always: localhost
host: 192.168.56.1
Oh I get it now. And now that I re-read your first message it was clear already, but my brain malfunctioned. :) Yeah it seems we should check strcmp return code as you suggest. Feel free to make a PR or I will do it later on.
@giampaolo thanks a lot! I just wanted to start the PR... ;-)
However, I can confirm that it now works (again) as expected.
I tested it with a VM with 1 login on console (tty7) and 1 remote SSH login (pts/1).
Now, fixed, correct (687695c289a84585b20f2037eee84fa11ca49b81):
In [3]: psutil.users()
Out[3]:
[suser(name='user', terminal='tty7', host='localhost', started=1731328029.0, pid=1273),
suser(name='user', terminal='pts/1', host='192.168.56.1', started=1731328170.0, pid=3439)]
=> host='192.168.56.1'
is now correct :smile:
For comparison, before, incorrect, with bug (3d12e67a9e4af3328660d4b3a81966555d7c98bf):
In [2]: psutil.users()
Out[2]:
[suser(name='user', terminal='tty7', host='localhost', started=1731328029.0, pid=1273),
suser(name='user', terminal='pts/1', host='localhost', started=1731328170.0, pid=3439)]
Summary
Description
For
python3 -c "import psutil; print(psutil.users())"
it gives always "host=localhost":suser(name='user', terminal='pts/1', host='localhost', started=..., pid=13535)
But, the expected is an IP (as long as getutent() doesn't produce ":0"/":0.0"), e.g.:
suser(name='user', terminal='pts/1', host='192.168.56.1', started=..., pid=13535)
With psutil version 5.9.0 I get the correct
host='192.168.56.1'
. With 6.1.0 it's always "localhost".Is it possible that the
strcmp
could be the problem?IS:
if (strcmp(ut->ut_host, ":0") || strcmp(ut->ut_host, ":0.0"))
SHOULD:
if (strcmp(ut->ut_host, ":0") == 0 || strcmp(ut->ut_host, ":0.0") == 0)
I would expect the IF to check whether host is ":0" or ":0.0".