Skip to content

Commit

Permalink
Fixes to net_connections() on FreeBSD. (#1079)
Browse files Browse the repository at this point in the history
* File descriptor 0 is a valid value, for example for a daemon.

* On FreeBSD fill in file descriptor values.

This not only removes ugly workaround from test_connections.py, but also
fixes several failures in this test.  Without file descriptor value, two
local sockets connected to each other, would be equal objects.  Since
in the _psbsd.py:net_connections(), the returned value is a Python set,
it will exclude any duplicates, resulting in shrinked list of sockets.
  • Loading branch information
glebius authored and giampaolo committed May 18, 2017
1 parent 61b6ed0 commit 5250b63
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 19 deletions.
30 changes: 16 additions & 14 deletions psutil/arch/freebsd/sys_socks.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ psutil_populate_xfiles() {
}


int
psutil_get_pid_from_sock(void *sock) {
struct xfile *
psutil_get_file_from_sock(void *sock) {
struct xfile *xf;
int n;

for (xf = psutil_xfiles, n = 0; n < psutil_nxfiles; ++n, ++xf) {
if (xf->xf_data == sock)
return xf->xf_pid;
return xf;
}
return -1;
return NULL;
}


Expand Down Expand Up @@ -129,7 +129,8 @@ int psutil_gather_inet(int proto, PyObject *py_retlist) {
} while (xig->xig_gen != exig->xig_gen && retry--);

for (;;) {
int lport, rport, pid, status, family;
struct xfile *xf;
int lport, rport, status, family;

xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
if (xig >= exig)
Expand Down Expand Up @@ -174,8 +175,8 @@ int psutil_gather_inet(int proto, PyObject *py_retlist) {

char lip[200], rip[200];

pid = psutil_get_pid_from_sock(so->xso_so);
if (pid < 0)
xf = psutil_get_file_from_sock(so->xso_so);
if (xf == NULL)
continue;
lport = ntohs(inp->inp_lport);
rport = ntohs(inp->inp_fport);
Expand Down Expand Up @@ -203,13 +204,13 @@ int psutil_gather_inet(int proto, PyObject *py_retlist) {
goto error;
py_tuple = Py_BuildValue(
"(iiiNNii)",
-1, // fd
xf->xf_fd, // fd
family, // family
type, // type
py_laddr, // laddr
py_raddr, // raddr
status, // status
pid); // pid
xf->xf_pid); // pid
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
Expand Down Expand Up @@ -238,7 +239,6 @@ int psutil_gather_unix(int proto, PyObject *py_retlist) {
size_t bufsize;
void *buf;
int retry;
int pid;
struct sockaddr_un *sun;
char path[PATH_MAX];

Expand Down Expand Up @@ -286,15 +286,17 @@ int psutil_gather_unix(int proto, PyObject *py_retlist) {
} while (xug->xug_gen != exug->xug_gen && retry--);

for (;;) {
struct xfile *xf;

xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
if (xug >= exug)
break;
xup = (struct xunpcb *)xug;
if (xup->xu_len != sizeof *xup)
goto error;

pid = psutil_get_pid_from_sock(xup->xu_socket.xso_so);
if (pid < 0)
xf = psutil_get_file_from_sock(xup->xu_socket.xso_so);
if (xf == NULL)
continue;

sun = (struct sockaddr_un *)&xup->xu_addr;
Expand All @@ -306,13 +308,13 @@ int psutil_gather_unix(int proto, PyObject *py_retlist) {
goto error;

py_tuple = Py_BuildValue("(iiiOsii)",
-1, // fd
xf->xf_fd, // fd
AF_UNIX, // family
proto, // type
py_lpath, // lpath
"", // rath
PSUTIL_CONN_NONE, // status
pid); // pid
xf->xf_pid); // pid
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
Expand Down
2 changes: 1 addition & 1 deletion psutil/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ def check_connection_ntuple(conn):

# check fd
if has_fd:
assert conn.fd > 0, conn
assert conn.fd >= 0, conn
if hasattr(socket, 'fromfd') and not WINDOWS:
try:
dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
Expand Down
4 changes: 0 additions & 4 deletions psutil/tests/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,6 @@ def compare_procsys_connections(self, pid, proc_cons, kind='all'):
raise
# Filter for this proc PID and exlucde PIDs from the tuple.
sys_cons = [c[:-1] for c in sys_cons if c.pid == pid]
if FREEBSD:
# On FreeBSD all fds are set to -1 so exclude them
# from comparison.
proc_cons = [pconn(*[-1] + list(x[1:])) for x in proc_cons]
sys_cons.sort()
proc_cons.sort()
self.assertEqual(proc_cons, sys_cons)
Expand Down

0 comments on commit 5250b63

Please sign in to comment.