int psutil_gather_unix()

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;
}