PyObject * psutil_proc_cwd(PyObject *self, PyObject *args) { // Reference: // http://anoncvs.spacehopper.org/openbsd-src/tree/bin/ps/print.c#n179 long pid; struct kinfo_proc kp; char path[MAXPATHLEN]; size_t pathlen = sizeof path; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; int name[] = { CTL_KERN, KERN_PROC_CWD, pid }; if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } #if PY_MAJOR_VERSION >= 3 return PyUnicode_DecodeFSDefault(path); #else return Py_BuildValue("s", path); #endif }
PyObject * psutil_proc_num_threads(PyObject *self, PyObject *args) { // Return number of threads used by process as a Python integer. long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("l", (long)kp.p_nlwps); }
PyObject * psutil_proc_cwd(PyObject *self, PyObject *args) { long pid; struct kinfo_file *freep = NULL; struct kinfo_file *kif; struct kinfo_proc kipp; const char *encoding_errs; PyObject *py_path = NULL; int i, cnt; if (! PyArg_ParseTuple(args, "l", &pid)) goto error; if (psutil_kinfo_proc(pid, &kipp) == -1) goto error; freep = kinfo_getfile(pid, &cnt); if (freep == NULL) { psutil_raise_ad_or_nsp(pid); goto error; } for (i = 0; i < cnt; i++) { kif = &freep[i]; if (kif->kf_fd == KF_FD_TYPE_CWD) { #if PY_MAJOR_VERSION >= 3 py_path = PyUnicode_DecodeFSDefault(kif->kf_path); #else py_path = Py_BuildValue("s", kif->kf_path); #endif if (!py_path) goto error; break; } } /* * For lower pids it seems we can't retrieve any information * (lsof can't do that it either). Since this happens even * as root we return an empty string instead of AccessDenied. */ if (py_path == NULL) py_path = Py_BuildValue("s", ""); free(freep); return py_path; error: Py_XDECREF(py_path); if (freep != NULL) free(freep); return NULL; }
/* * Return a Python float indicating the process create time expressed in * seconds since the epoch. */ static PyObject * psutil_proc_create_time(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; #ifdef __FreeBSD__ return Py_BuildValue("d", PSUTIL_TV2DOUBLE(kp.ki_start)); #elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("d", PSUTIL_KPT2DOUBLE(kp.p_ustart)); #endif }
/* * Return process real, effective and saved group ids from kinfo_proc * as a Python tuple. */ static PyObject * psutil_proc_tty_nr(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; #ifdef __FreeBSD__ return Py_BuildValue("i", kp.ki_tdev); #elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("i", kp.p_tdev); #endif }
/* * Return the number of context switches performed by process as a tuple. */ static PyObject * psutil_proc_num_ctx_switches(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("(ll)", #ifdef __FreeBSD__ kp.ki_rusage.ru_nvcsw, kp.ki_rusage.ru_nivcsw); #elif defined(__OpenBSD__) || defined(__NetBSD__) kp.p_uru_nvcsw, kp.p_uru_nivcsw); #endif }
/* * Return a Python tuple (user_time, kernel_time) */ static PyObject * psutil_proc_cpu_times(PyObject *self, PyObject *args) { long pid; double user_t, sys_t; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; // convert from microseconds to seconds #ifdef __FreeBSD__ user_t = PSUTIL_TV2DOUBLE(kp.ki_rusage.ru_utime); sys_t = PSUTIL_TV2DOUBLE(kp.ki_rusage.ru_stime); #elif defined(__OpenBSD__) || defined(__NetBSD__) user_t = PSUTIL_KPT2DOUBLE(kp.p_uutime); sys_t = PSUTIL_KPT2DOUBLE(kp.p_ustime); #endif return Py_BuildValue("(dd)", user_t, sys_t); }
/* * Return process real, effective and saved group ids from kinfo_proc * as a Python tuple. */ static PyObject * psutil_proc_gids(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("lll", #ifdef __FreeBSD__ (long)kp.ki_rgid, (long)kp.ki_groups[0], (long)kp.ki_svuid); #elif defined(__OpenBSD__) || defined(__NetBSD__) (long)kp.p_rgid, (long)kp.p_groups[0], (long)kp.p_svuid); #endif }
/* * Return a Python float indicating the process create time expressed in * seconds since the epoch. */ static PyObject * psutil_proc_io_counters(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; // there's apparently no way to determine bytes count, hence return -1. return Py_BuildValue("(llll)", #ifdef __FreeBSD__ kp.ki_rusage.ru_inblock, kp.ki_rusage.ru_oublock, #elif defined(__OpenBSD__) || defined(__NetBSD__) kp.p_uru_inblock, kp.p_uru_oublock, #endif -1, -1); }
PyObject * psutil_proc_num_fds(PyObject *self, PyObject *args) { long pid; int cnt; struct kinfo_file *freep; struct kinfo_proc kipp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kipp) == -1) return NULL; freep = kinfo_getfile(pid, &cnt); if (freep == NULL) { psutil_raise_ad_or_nsp(pid); return NULL; } free(freep); return Py_BuildValue("i", cnt); }
/* * Return process name from kinfo_proc as a Python string. */ static PyObject * psutil_proc_name(PyObject *self, PyObject *args) { long pid; kinfo_proc kp; char str[1000]; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; #ifdef __FreeBSD__ sprintf(str, "%s", kp.ki_comm); #elif defined(__OpenBSD__) || defined(__NetBSD__) sprintf(str, "%s", kp.p_comm); #endif #if PY_MAJOR_VERSION >= 3 return PyUnicode_DecodeFSDefault(str); #else return Py_BuildValue("s", str); #endif }
/* * Return extended memory info for a process as a Python tuple. */ static PyObject * psutil_proc_memory_info(PyObject *self, PyObject *args) { long pagesize = sysconf(_SC_PAGESIZE); long pid; kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue( "(lllll)", #ifdef __FreeBSD__ (long) kp.ki_rssize * pagesize, // rss (long) kp.ki_size, // vms (long) kp.ki_tsize * pagesize, // text (long) kp.ki_dsize * pagesize, // data (long) kp.ki_ssize * pagesize // stack #else (long) kp.p_vm_rssize * pagesize, // rss #ifdef __OpenBSD__ // VMS, this is how ps determines it on OpenBSD: // http://anoncvs.spacehopper.org/openbsd-src/tree/bin/ps/print.c#n461 // vms (long) (kp.p_vm_dsize + kp.p_vm_ssize + kp.p_vm_tsize) * pagesize, #elif __NetBSD__ // VMS, this is how top determines it on NetBSD: // ftp://ftp.iij.ad.jp/pub/NetBSD/NetBSD-release-6/src/external/bsd/ // top/dist/machine/m_netbsd.c (long) kp.p_vm_msize * pagesize, // vms #endif (long) kp.p_vm_tsize * pagesize, // text (long) kp.p_vm_dsize * pagesize, // data (long) kp.p_vm_ssize * pagesize // stack #endif ); }
PyObject * psutil_proc_memory_maps(PyObject *self, PyObject *args) { // Return a list of tuples for every process memory maps. //'procstat' cmdline utility has been used as an example. long pid; int ptrwidth; int i, cnt; char addr[1000]; char perms[4]; const char *path; struct kinfo_proc kp; struct kinfo_vmentry *freep = NULL; struct kinfo_vmentry *kve; ptrwidth = 2 * sizeof(void *); PyObject *py_tuple = NULL; PyObject *py_retlist = PyList_New(0); if (py_retlist == NULL) return NULL; if (! PyArg_ParseTuple(args, "l", &pid)) goto error; if (psutil_kinfo_proc(pid, &kp) == -1) goto error; freep = kinfo_getvmmap(pid, &cnt); if (freep == NULL) { psutil_raise_ad_or_nsp(pid); goto error; } for (i = 0; i < cnt; i++) { py_tuple = NULL; kve = &freep[i]; addr[0] = '\0'; perms[0] = '\0'; sprintf(addr, "%#*jx-%#*jx", ptrwidth, (uintmax_t)kve->kve_start, ptrwidth, (uintmax_t)kve->kve_end); psutil_remove_spaces(addr); strlcat(perms, kve->kve_protection & KVME_PROT_READ ? "r" : "-", sizeof(perms)); strlcat(perms, kve->kve_protection & KVME_PROT_WRITE ? "w" : "-", sizeof(perms)); strlcat(perms, kve->kve_protection & KVME_PROT_EXEC ? "x" : "-", sizeof(perms)); if (strlen(kve->kve_path) == 0) { switch (kve->kve_type) { case KVME_TYPE_NONE: path = "[none]"; break; case KVME_TYPE_DEFAULT: path = "[default]"; break; case KVME_TYPE_VNODE: path = "[vnode]"; break; case KVME_TYPE_SWAP: path = "[swap]"; break; case KVME_TYPE_DEVICE: path = "[device]"; break; case KVME_TYPE_PHYS: path = "[phys]"; break; case KVME_TYPE_DEAD: path = "[dead]"; break; case KVME_TYPE_SG: path = "[sg]"; break; case KVME_TYPE_UNKNOWN: path = "[unknown]"; break; default: path = "[?]"; break; } } else { path = kve->kve_path; } py_tuple = Py_BuildValue("sssiiii", addr, // "start-end" address perms, // "rwx" permissions path, // path kve->kve_resident, // rss kve->kve_private_resident, // private kve->kve_ref_count, // ref count kve->kve_shadow_count); // shadow count if (!py_tuple) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); } free(freep); return py_retlist; error: Py_XDECREF(py_tuple); Py_DECREF(py_retlist); if (freep != NULL) free(freep); return NULL; }
static PyObject * psutil_proc_open_files(PyObject *self, PyObject *args) { long pid; int i, cnt; struct kinfo_file *freep = NULL; struct kinfo_file *kif; kinfo_proc kipp; PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; if (py_retlist == NULL) return NULL; if (! PyArg_ParseTuple(args, "l", &pid)) goto error; if (psutil_kinfo_proc(pid, &kipp) == -1) goto error; freep = kinfo_getfile(pid, &cnt); if (freep == NULL) { psutil_raise_ad_or_nsp(pid); goto error; } for (i = 0; i < cnt; i++) { kif = &freep[i]; #ifdef __FreeBSD__ if ((kif->kf_type == KF_TYPE_VNODE) && (kif->kf_vnode_type == KF_VTYPE_VREG)) { py_tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd); #elif defined(__OpenBSD__) if ((kif->f_type == DTYPE_VNODE) && (kif->v_type == VREG)) { py_tuple = Py_BuildValue("(si)", "", kif->fd_fd); #elif defined(__NetBSD__) if ((kif->ki_ftype == DTYPE_VNODE) && (kif->ki_vtype == VREG)) { py_tuple = Py_BuildValue("(si)", "", kif->ki_fd); #endif if (py_tuple == NULL) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); } } free(freep); return py_retlist; error: Py_XDECREF(py_tuple); Py_DECREF(py_retlist); if (freep != NULL) free(freep); return NULL; } #endif /* * Return a list of tuples including device, mount point and fs type * for all partitions mounted on the system. */ static PyObject * psutil_disk_partitions(PyObject *self, PyObject *args) { int num; int i; long len; uint64_t flags; char opts[200]; #if defined(__NetBSD__) struct statvfs *fs = NULL; #else struct statfs *fs = NULL; #endif PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; if (py_retlist == NULL) return NULL; // get the number of mount points Py_BEGIN_ALLOW_THREADS #if defined(__NetBSD__) num = getvfsstat(NULL, 0, MNT_NOWAIT); #else num = getfsstat(NULL, 0, MNT_NOWAIT); #endif Py_END_ALLOW_THREADS if (num == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } len = sizeof(*fs) * num; fs = malloc(len); if (fs == NULL) { PyErr_NoMemory(); goto error; } Py_BEGIN_ALLOW_THREADS #if defined(__NetBSD__) num = getvfsstat(fs, len, MNT_NOWAIT); #else num = getfsstat(fs, len, MNT_NOWAIT); #endif Py_END_ALLOW_THREADS if (num == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } for (i = 0; i < num; i++) { py_tuple = NULL; opts[0] = 0; #if defined(__NetBSD__) flags = fs[i].f_flag; #else flags = fs[i].f_flags; #endif // see sys/mount.h if (flags & MNT_RDONLY) strlcat(opts, "ro", sizeof(opts)); else strlcat(opts, "rw", sizeof(opts)); if (flags & MNT_SYNCHRONOUS) strlcat(opts, ",sync", sizeof(opts)); if (flags & MNT_NOEXEC) strlcat(opts, ",noexec", sizeof(opts)); if (flags & MNT_NOSUID) strlcat(opts, ",nosuid", sizeof(opts)); if (flags & MNT_ASYNC) strlcat(opts, ",async", sizeof(opts)); if (flags & MNT_NOATIME) strlcat(opts, ",noatime", sizeof(opts)); if (flags & MNT_SOFTDEP) strlcat(opts, ",softdep", sizeof(opts)); #ifdef __FreeBSD__ if (flags & MNT_UNION) strlcat(opts, ",union", sizeof(opts)); if (flags & MNT_SUIDDIR) strlcat(opts, ",suiddir", sizeof(opts)); if (flags & MNT_SOFTDEP) strlcat(opts, ",softdep", sizeof(opts)); if (flags & MNT_NOSYMFOLLOW) strlcat(opts, ",nosymfollow", sizeof(opts)); if (flags & MNT_GJOURNAL) strlcat(opts, ",gjournal", sizeof(opts)); if (flags & MNT_MULTILABEL) strlcat(opts, ",multilabel", sizeof(opts)); if (flags & MNT_ACLS) strlcat(opts, ",acls", sizeof(opts)); if (flags & MNT_NOCLUSTERR) strlcat(opts, ",noclusterr", sizeof(opts)); if (flags & MNT_NOCLUSTERW) strlcat(opts, ",noclusterw", sizeof(opts)); if (flags & MNT_NFS4ACLS) strlcat(opts, ",nfs4acls", sizeof(opts)); #elif __NetBSD__ if (flags & MNT_NODEV) strlcat(opts, ",nodev", sizeof(opts)); if (flags & MNT_UNION) strlcat(opts, ",union", sizeof(opts)); if (flags & MNT_NOCOREDUMP) strlcat(opts, ",nocoredump", sizeof(opts)); if (flags & MNT_RELATIME) strlcat(opts, ",relatime", sizeof(opts)); if (flags & MNT_IGNORE) strlcat(opts, ",ignore", sizeof(opts)); #if defined(MNT_DISCARD) if (flags & MNT_DISCARD) strlcat(opts, ",discard", sizeof(opts)); #endif if (flags & MNT_EXTATTR) strlcat(opts, ",extattr", sizeof(opts)); if (flags & MNT_LOG) strlcat(opts, ",log", sizeof(opts)); if (flags & MNT_SYMPERM) strlcat(opts, ",symperm", sizeof(opts)); if (flags & MNT_NODEVMTIME) strlcat(opts, ",nodevmtime", sizeof(opts)); #endif py_tuple = Py_BuildValue("(ssss)", fs[i].f_mntfromname, // device fs[i].f_mntonname, // mount point fs[i].f_fstypename, // fs type opts); // options if (!py_tuple) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); } free(fs); return py_retlist; error: Py_XDECREF(py_tuple); Py_DECREF(py_retlist); if (fs != NULL) free(fs); return NULL; } /* * Return a Python list of named tuples with overall network I/O information */ static PyObject * psutil_net_io_counters(PyObject *self, PyObject *args) { char *buf = NULL, *lim, *next; struct if_msghdr *ifm; int mib[6]; size_t len; PyObject *py_retdict = PyDict_New(); PyObject *py_ifc_info = NULL; if (py_retdict == NULL) return NULL; mib[0] = CTL_NET; // networking subsystem mib[1] = PF_ROUTE; // type of information mib[2] = 0; // protocol (IPPROTO_xxx) mib[3] = 0; // address family mib[4] = NET_RT_IFLIST; // operation mib[5] = 0; if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); goto error; } buf = malloc(len); if (buf == NULL) { PyErr_NoMemory(); goto error; } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); goto error; } lim = buf + len; for (next = buf; next < lim; ) { py_ifc_info = NULL; ifm = (struct if_msghdr *)next; next += ifm->ifm_msglen; if (ifm->ifm_type == RTM_IFINFO) { struct if_msghdr *if2m = (struct if_msghdr *)ifm; struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1); char ifc_name[32]; strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen); ifc_name[sdl->sdl_nlen] = 0; // XXX: ignore usbus interfaces: // http://lists.freebsd.org/pipermail/freebsd-current/ // 2011-October/028752.html // 'ifconfig -a' doesn't show them, nor do we. if (strncmp(ifc_name, "usbus", 5) == 0) continue; py_ifc_info = Py_BuildValue("(kkkkkkki)", if2m->ifm_data.ifi_obytes, if2m->ifm_data.ifi_ibytes, if2m->ifm_data.ifi_opackets, if2m->ifm_data.ifi_ipackets, if2m->ifm_data.ifi_ierrors, if2m->ifm_data.ifi_oerrors, if2m->ifm_data.ifi_iqdrops, 0); // dropout not supported if (!py_ifc_info) goto error; if (PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info)) goto error; Py_DECREF(py_ifc_info); } else { continue; } } free(buf); return py_retdict; error: Py_XDECREF(py_ifc_info); Py_DECREF(py_retdict); if (buf != NULL) free(buf); return NULL; }