in ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_bsd.c [1914:2010]
int psutil_gather_unix(int proto, PyObject *py_retlist)
{
struct xunpgen *xug, *exug;
struct xunpcb *xup;
struct sock *sock;
const char *varname, *protoname;
size_t len, bufsize;
void *buf;
int hash, retry;
int family, lport, rport, pid;
struct sockaddr_un *sun;
char path[PATH_MAX];
PyObject *tuple = NULL;
PyObject *laddr = NULL;
PyObject *raddr = NULL;
switch (proto) {
case SOCK_STREAM:
varname = "net.local.stream.pcblist";
protoname = "stream";
break;
case SOCK_DGRAM:
varname = "net.local.dgram.pcblist";
protoname = "dgram";
break;
}
buf = NULL;
bufsize = 8192;
retry = 5;
do {
for (;;) {
buf = realloc(buf, bufsize);
if (buf == NULL) {
PyErr_NoMemory();
goto error;
}
len = bufsize;
if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
break;
if (errno != ENOMEM) {
PyErr_SetFromErrno(0);
goto error;
}
bufsize *= 2;
}
xug = (struct xunpgen *)buf;
exug = (struct xunpgen *)(void *)
((char *)buf + len - sizeof *exug);
if (xug->xug_len != sizeof *xug || exug->xug_len != sizeof *exug) {
PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
goto error;
}
} while (xug->xug_gen != exug->xug_gen && retry--);
for (;;) {
xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
if (xug >= exug)
break;
xup = (struct xunpcb *)xug;
if (xup->xu_len != sizeof *xup) {
warnx("struct xunpgen size mismatch");
goto error;
}
hash = (int)((uintptr_t) xup->xu_socket.xso_so % HASHSIZE);
pid = psutil_get_pid_from_sock(hash);
if (pid < 0)
continue;
sun = (struct sockaddr_un *)&xup->xu_addr;
snprintf(path, sizeof(path), "%.*s",
(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
sun->sun_path);
tuple = Py_BuildValue("(iiisOii)", -1, AF_UNIX, proto, path, Py_None,
PSUTIL_CONN_NONE, pid);
if (!tuple)
goto error;
if (PyList_Append(py_retlist, tuple))
goto error;
Py_DECREF(tuple);
Py_INCREF(Py_None);
}
free(buf);
return 1;
error:
Py_XDECREF(tuple);
Py_XDECREF(laddr);
Py_XDECREF(raddr);
free(buf);
return 0;
}