From 312442ad2a5b5d0c608476c5ab3e267735c3bc59 Mon Sep 17 00:00:00 2001 From: Ryo ONODERA Date: Wed, 30 Dec 2015 03:46:51 +0100 Subject: [PATCH 01/26] Add NetBSD support. Signed-off-by: Thomas Klausner --- psutil/__init__.py | 2 +- psutil/_psbsd.py | 40 +- psutil/_psutil_bsd.c | 162 +++++--- psutil/_psutil_posix.c | 10 +- psutil/arch/bsd/netbsd.c | 662 +++++++++++++++++++++++++++++++++ psutil/arch/bsd/netbsd.h | 30 ++ psutil/arch/bsd/netbsd_socks.c | 535 ++++++++++++++++++++++++++ psutil/arch/bsd/netbsd_socks.h | 10 + setup.py | 13 + test/test_psutil.py | 3 +- 10 files changed, 1404 insertions(+), 63 deletions(-) create mode 100644 psutil/arch/bsd/netbsd.c create mode 100644 psutil/arch/bsd/netbsd.h create mode 100644 psutil/arch/bsd/netbsd_socks.c create mode 100644 psutil/arch/bsd/netbsd_socks.h diff --git a/psutil/__init__.py b/psutil/__init__.py index 727b1b649..e30645aa9 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -123,7 +123,7 @@ elif sys.platform.startswith("darwin"): from . import _psosx as _psplatform -elif sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd"): +elif sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd") or sys.platform.startswith("netbsd"): from . import _psbsd as _psplatform elif sys.platform.startswith("sunos"): diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index a772e2646..89f29c76a 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -28,6 +28,7 @@ FREEBSD = sys.platform.startswith("freebsd") OPENBSD = sys.platform.startswith("openbsd") +NETBSD = sys.platform.startswith("netbsd") if FREEBSD: PROC_STATUSES = { @@ -60,6 +61,15 @@ cext.SRUN: _common.STATUS_WAKING, cext.SONPROC: _common.STATUS_RUNNING, } +elif NETBSD: + PROC_STATUSES = { + cext.SIDL: _common.STATUS_IDLE, + cext.SACTIVE: _common.STATUS_RUNNING, + cext.SDYING: _common.STATUS_ZOMBIE, + cext.SSTOP: _common.STATUS_STOPPED, + cext.SZOMB: _common.STATUS_ZOMBIE, + cext.SDEAD: _common.STATUS_DEAD, + } TCP_STATUSES = { cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, @@ -76,7 +86,10 @@ cext.PSUTIL_CONN_NONE: _common.CONN_NONE, } -PAGESIZE = os.sysconf("SC_PAGE_SIZE") +if NETBSD: + PAGESIZE = os.sysconf("SC_PAGESIZE") +else: + PAGESIZE = os.sysconf("SC_PAGE_SIZE") AF_LINK = cext_posix.AF_LINK # extend base mem ntuple with BSD-specific memory metrics @@ -156,9 +169,9 @@ def cpu_count_logical(): return cext.cpu_count_logical() -if OPENBSD: +if OPENBSD or NETBSD: def cpu_count_physical(): - # OpenBSD does not implement this. + # OpenBSD and NetBSD do not implement this. return 1 if cpu_count_logical() == 1 else None else: def cpu_count_physical(): @@ -273,7 +286,7 @@ def net_if_stats(): return ret -if OPENBSD: +if OPENBSD or NETBSD: def pid_exists(pid): exists = _psposix.pid_exists(pid) if not exists: @@ -333,7 +346,7 @@ def name(self): @wrap_exceptions def exe(self): - if FREEBSD: + if FREEBSD or NETBSD: return cext.proc_exe(self.pid) else: # exe cannot be determined on OpenBSD; references: @@ -423,6 +436,23 @@ def threads(self): @wrap_exceptions def connections(self, kind='inet'): + if NETBSD: + families, types = conn_tmap[kind] + ret = set() + rawlist = cext.proc_connections(self.pid) + for item in rawlist: + fd, fam, type, laddr, raddr, status = item + if fam in families and type in types: + try: + status = TCP_STATUSES[status] + except KeyError: + status = TCP_STATUSES[cext.PSUTIL_CONN_NONE] + fam = sockfam_to_enum(fam) + type = socktype_to_enum(type) + nt = _common.pconn(fd, fam, type, laddr, raddr, status) + ret.add(nt) + return list(ret) + if kind not in conn_tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in conn_tmap]))) diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 278504f81..6c194e8b5 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -15,6 +15,9 @@ * - psutil.Process.memory_maps() */ +#if defined(__NetBSD__) +#define _KMEMUSER +#endif #include #include @@ -42,6 +45,7 @@ #include #include #include +#include #include // for struct xtcpcb #include // for TCP connection states #include // for inet_ntop() @@ -63,6 +67,9 @@ #include "arch/bsd/freebsd_socks.h" #elif __OpenBSD__ #include "arch/bsd/openbsd.h" +#elif __NetBSD__ + #include "arch/bsd/netbsd.h" + #include "arch/bsd/netbsd_socks.h" #endif #ifdef __FreeBSD__ @@ -85,6 +92,15 @@ #include // for CPUSTATES & CP_* #endif +#if defined(__NetBSD__) + #include + #include // for VREG + #include // for CPUSTATES & CP_* +#define _KERNEL + #include +#undef _KERNEL +#endif + // convert a timeval struct to a double #define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) @@ -95,7 +111,7 @@ (uint32_t) (bt.frac >> 32) ) >> 32 ) / 1000000) #endif -#ifdef __OpenBSD__ +#if defined(__OpenBSD__) || defined (__NetBSD__) #define PSUTIL_KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0) #endif @@ -125,7 +141,7 @@ psutil_pids(PyObject *self, PyObject *args) { for (idx = 0; idx < num_processes; idx++) { #ifdef __FreeBSD__ py_pid = Py_BuildValue("i", proclist->ki_pid); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) py_pid = Py_BuildValue("i", proclist->p_pid); #endif if (!py_pid) @@ -174,14 +190,14 @@ psutil_boot_time(PyObject *self, PyObject *args) { static PyObject * psutil_proc_name(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + 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("s", kp.ki_comm); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("s", kp.p_comm); #endif } @@ -213,14 +229,14 @@ psutil_proc_cmdline(PyObject *self, PyObject *args) { static PyObject * psutil_proc_ppid(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + 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("l", (long)kp.ki_ppid); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("l", (long)kp.p_ppid); #endif } @@ -232,14 +248,14 @@ psutil_proc_ppid(PyObject *self, PyObject *args) { static PyObject * psutil_proc_status(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + 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", (int)kp.ki_stat); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("i", (int)kp.p_stat); #endif } @@ -252,7 +268,7 @@ psutil_proc_status(PyObject *self, PyObject *args) { static PyObject * psutil_proc_uids(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -262,7 +278,7 @@ psutil_proc_uids(PyObject *self, PyObject *args) { (long)kp.ki_ruid, (long)kp.ki_uid, (long)kp.ki_svuid); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) (long)kp.p_ruid, (long)kp.p_uid, (long)kp.p_svuid); @@ -277,7 +293,7 @@ psutil_proc_uids(PyObject *self, PyObject *args) { static PyObject * psutil_proc_gids(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -287,7 +303,7 @@ psutil_proc_gids(PyObject *self, PyObject *args) { (long)kp.ki_rgid, (long)kp.ki_groups[0], (long)kp.ki_svuid); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) (long)kp.p_rgid, (long)kp.p_groups[0], (long)kp.p_svuid); @@ -302,14 +318,14 @@ psutil_proc_gids(PyObject *self, PyObject *args) { static PyObject * psutil_proc_tty_nr(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + 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 __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("i", kp.p_tdev); #endif } @@ -321,7 +337,7 @@ psutil_proc_tty_nr(PyObject *self, PyObject *args) { static PyObject * psutil_proc_num_ctx_switches(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -330,7 +346,7 @@ psutil_proc_num_ctx_switches(PyObject *self, PyObject *args) { #ifdef __FreeBSD__ kp.ki_rusage.ru_nvcsw, kp.ki_rusage.ru_nivcsw); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) kp.p_uru_nvcsw, kp.p_uru_nivcsw); #endif @@ -344,7 +360,7 @@ static PyObject * psutil_proc_cpu_times(PyObject *self, PyObject *args) { long pid; double user_t, sys_t; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -353,7 +369,7 @@ psutil_proc_cpu_times(PyObject *self, PyObject *args) { #ifdef __FreeBSD__ user_t = PSUTIL_TV2DOUBLE(kp.ki_rusage.ru_utime); sys_t = PSUTIL_TV2DOUBLE(kp.ki_rusage.ru_stime); -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) user_t = PSUTIL_KPT2DOUBLE(kp.p_uutime); sys_t = PSUTIL_KPT2DOUBLE(kp.p_ustime); #endif @@ -389,14 +405,14 @@ psutil_cpu_count_logical(PyObject *self, PyObject *args) { static PyObject * psutil_proc_create_time(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + 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 __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) return Py_BuildValue("d", PSUTIL_KPT2DOUBLE(kp.p_ustart)); #endif } @@ -409,7 +425,7 @@ psutil_proc_create_time(PyObject *self, PyObject *args) { static PyObject * psutil_proc_io_counters(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -419,7 +435,7 @@ psutil_proc_io_counters(PyObject *self, PyObject *args) { #ifdef __FreeBSD__ kp.ki_rusage.ru_inblock, kp.ki_rusage.ru_oublock, -#elif __OpenBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) kp.p_uru_inblock, kp.p_uru_oublock, #endif @@ -438,7 +454,7 @@ psutil_proc_io_counters(PyObject *self, PyObject *args) { static PyObject * psutil_proc_memory_info(PyObject *self, PyObject *args) { long pid; - struct kinfo_proc kp; + kinfo_proc kp; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) @@ -451,7 +467,7 @@ psutil_proc_memory_info(PyObject *self, PyObject *args) { ptoa(kp.ki_tsize), // text ptoa(kp.ki_dsize), // data ptoa(kp.ki_ssize)); // stack -#elif __OpenBSD__ +#elif defined(__OpenBSD__) ptoa(kp.p_vm_rssize), // rss // vms, this is how ps does it, see: // http://anoncvs.spacehopper.org/openbsd-src/tree/bin/ps/print.c#n461 @@ -459,6 +475,9 @@ psutil_proc_memory_info(PyObject *self, PyObject *args) { ptoa(kp.p_vm_tsize), // text ptoa(kp.p_vm_dsize), // data ptoa(kp.p_vm_ssize)); // stack +#else +/* not implemented */ + 0, 0, 0, 0, 0); #endif } @@ -472,7 +491,7 @@ psutil_cpu_times(PyObject *self, PyObject *args) { size_t size = sizeof(cpu_time); int ret; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) ret = sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0); #elif __OpenBSD__ int mib[] = {CTL_KERN, KERN_CPTIME}; @@ -499,14 +518,14 @@ psutil_cpu_times(PyObject *self, PyObject *args) { * utility has the same problem see: * https://github.com/giampaolo/psutil/issues/595 */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ +#if (defined(__FreeBSD_version) && __FreeBSD_version >= 800000) || __OpenBSD__ || defined(__NetBSD__) static PyObject * psutil_proc_open_files(PyObject *self, PyObject *args) { long pid; int i, cnt; struct kinfo_file *freep = NULL; struct kinfo_file *kif; - struct kinfo_proc kipp; + kinfo_proc kipp; PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; @@ -530,11 +549,16 @@ psutil_proc_open_files(PyObject *self, PyObject *args) { (kif->kf_vnode_type == KF_VTYPE_VREG)) { py_tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd); -#else +#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; @@ -567,7 +591,11 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { 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; @@ -576,7 +604,11 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { // 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); @@ -591,7 +623,11 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { } 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); @@ -601,24 +637,32 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { 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)); -#ifdef __FreeBSD__ 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_UNION) - strlcat(opts, ",union", 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) @@ -631,27 +675,33 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { strlcat(opts, ",multilabel", sizeof(opts)); if (flags & MNT_ACLS) strlcat(opts, ",acls", sizeof(opts)); - if (flags & MNT_NOATIME) - strlcat(opts, ",noatime", 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 __OpenBSD__ - 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_SOFTDEP) - strlcat(opts, ",softdep", sizeof(opts)); - if (flags & MNT_NOATIME) - strlcat(opts, ",noatime", 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 (flags & MNT_DISCARD) + strlcat(opts, ",discard", sizeof(opts)); + 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 @@ -778,7 +828,7 @@ psutil_users(PyObject *self, PyObject *args) { if (py_retlist == NULL) return NULL; -#if __FreeBSD_version < 900000 || __OpenBSD__ +#if (defined(__FreeBSD_version) && (__FreeBSD_version < 900000)) || __OpenBSD__ struct utmp ut; FILE *fp; @@ -812,6 +862,7 @@ psutil_users(PyObject *self, PyObject *args) { #else struct utmpx *utx; + setutxent(); while ((utx = getutxent()) != NULL) { if (utx->ut_type != USER_PROCESS) continue; @@ -883,20 +934,21 @@ PsutilMethods[] = { "Return process tty (terminal) number"}, {"proc_cwd", psutil_proc_cwd, METH_VARARGS, "Return process current working directory."}, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ || defined(__NetBSD__) {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS, "Return the number of file descriptors opened by this process"}, #endif -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ || defined(__NetBSD__) {"proc_open_files", psutil_proc_open_files, METH_VARARGS, "Return files opened by process as a list of (path, fd) tuples"}, #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) {"proc_exe", psutil_proc_exe, METH_VARARGS, "Return process pathname executable"}, {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS, "Return number of threads used by process"}, +#if defined(__FreeBSD__) {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS, "Return a list of tuples for every process's memory map"}, {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS, @@ -905,6 +957,7 @@ PsutilMethods[] = { "Set process CPU affinity."}, {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS, "Return an XML string to determine the number physical CPUs."}, +#endif #endif // --- system-related functions @@ -932,7 +985,7 @@ PsutilMethods[] = { "Return a Python dict of tuples for disk I/O information"}, {"users", psutil_users, METH_VARARGS, "Return currently connected users as a list of tuples"}, -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) {"net_connections", psutil_net_connections, METH_VARARGS, "Return system-wide open connections."}, #endif @@ -1010,6 +1063,13 @@ void init_psutil_bsd(void) PyModule_AddIntConstant(module, "SZOMB", SZOMB); // unused PyModule_AddIntConstant(module, "SDEAD", SDEAD); PyModule_AddIntConstant(module, "SONPROC", SONPROC); +#elif defined(__NetBSD__) + PyModule_AddIntConstant(module, "SIDL", SIDL); + PyModule_AddIntConstant(module, "SACTIVE", SACTIVE); + PyModule_AddIntConstant(module, "SDYING", SDYING); + PyModule_AddIntConstant(module, "SSTOP", SSTOP); + PyModule_AddIntConstant(module, "SZOMB", SZOMB); + PyModule_AddIntConstant(module, "SDEAD", SDEAD); #endif // connection status constants diff --git a/psutil/_psutil_posix.c b/psutil/_psutil_posix.c index 074042061..55bfec9a1 100644 --- a/psutil/_psutil_posix.c +++ b/psutil/_psutil_posix.c @@ -26,7 +26,7 @@ #include #endif // end linux -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) #include #include #include @@ -120,7 +120,7 @@ psutil_convert_ipaddr(struct sockaddr *addr, int family) { data = (const char *)lladdr->sll_addr; } #endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) else if (addr->sa_family == AF_LINK) { // Note: prior to Python 3.4 socket module does not expose // AF_LINK so we'll do. @@ -250,7 +250,7 @@ psutil_net_if_addrs(PyObject* self, PyObject* args) { * net_if_stats() implementation. This is here because it is common * to both OSX and FreeBSD and I didn't know where else to put it. */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) #include #include @@ -478,7 +478,7 @@ PsutilMethods[] = { "Set process priority"}, {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS, "Retrieve NICs information"}, -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) {"net_if_stats", psutil_net_if_stats, METH_VARARGS, "Return NIC stats."}, #endif @@ -537,7 +537,7 @@ void init_psutil_posix(void) PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods); #endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__sun) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__sun) || defined(__NetBSD__) PyModule_AddIntConstant(module, "AF_LINK", AF_LINK); #endif diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c new file mode 100644 index 000000000..4bc30a2a5 --- /dev/null +++ b/psutil/arch/bsd/netbsd.c @@ -0,0 +1,662 @@ +/* + * Copyright (c) 2009, Giampaolo Rodola', Landry Breuil. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Platform-specific module methods for NetBSD. + */ + +#if defined(__NetBSD__) +#define _KMEMUSER +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for swap_mem +#include +#include +// connection stuff +#include // for NI_MAXHOST +#include +#include // for CPUSTATES & CP_* +#define _KERNEL // for DTYPE_* +#include +#undef _KERNEL +#include // struct diskstats +#include +#include + + +#include "netbsd.h" +#include "netbsd_socks.h" + +#define PSUTIL_KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0) +#define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) + + +// ============================================================================ +// Utility functions +// ============================================================================ + +int +psutil_kinfo_proc(pid_t pid, kinfo_proc *proc) { + // Fills a kinfo_proc struct based on process pid. + int ret; + int mib[6]; + size_t size = sizeof(kinfo_proc); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC2; + mib[2] = KERN_PROC_PID; + mib[3] = pid; + mib[4] = size; + mib[5] = 1; + + ret = sysctl((int*)mib, 6, proc, &size, NULL, 0); + if (ret == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + // sysctl stores 0 in the size if we can't find the process information. + if (size == 0) { + NoSuchProcess(); + return -1; + } + return 0; +} + + +struct kinfo_file * +kinfo_getfile(pid_t pid, int* cnt) { + // Mimic's FreeBSD kinfo_file call, taking a pid and a ptr to an + // int as arg and returns an array with cnt struct kinfo_file. + int mib[6]; + size_t len; + struct kinfo_file* kf; + mib[0] = CTL_KERN; + mib[1] = KERN_FILE2; + mib[2] = KERN_FILE_BYPID; + mib[3] = (int) pid; + mib[4] = sizeof(struct kinfo_file); + mib[5] = 0; + + /* get the size of what would be returned */ + if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if ((kf = malloc(len)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + mib[5] = (int)(len / sizeof(struct kinfo_file)); + if (sysctl(mib, 6, kf, &len, NULL, 0) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + *cnt = (int)(len / sizeof(struct kinfo_file)); + return kf; +} + + +int +psutil_pid_exists(pid_t pid) { + // Return 1 if PID exists in the current process list, else 0, -1 + // on error. + // TODO: this should live in _psutil_posix.c but for some reason if I + // move it there I get a "include undefined symbol" error. + int ret; + if (pid < 0) + return 0; + ret = kill(pid , 0); + if (ret == 0) + return 1; + else { + if (ret == ESRCH) + return 0; + else if (ret == EPERM) + return 1; + else { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + } +} + +PyObject * +psutil_proc_exe(PyObject *self, PyObject *args) { +#if __NetBSD_Version__ >= 799000000 + pid_t pid; + char pathname[MAXPATHLEN]; + int error; + int mib[4]; + int ret; + size_t size; + + if (! PyArg_ParseTuple(args, "l", &pid)) + return NULL; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = pid; + mib[3] = KERN_PROC_PATHNAME; + + size = sizeof(pathname); + error = sysctl(mib, 4, NULL, &size, NULL, 0); + if (error == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + error = sysctl(mib, 4, pathname, &size, NULL, 0); + if (error == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (size == 0 || strlen(pathname) == 0) { + ret = psutil_pid_exists(pid); + if (ret == -1) + return NULL; + else if (ret == 0) + return NoSuchProcess(); + else + strcpy(pathname, ""); + } + return Py_BuildValue("s", pathname); +#else + return NULL; +#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_threads(PyObject *self, PyObject *args) { + pid_t pid; + int mib[5]; + int i, nlwps; + ssize_t st; + size_t size; + struct kinfo_lwp *kl; + PyObject *py_retlist = PyList_New(0); + PyObject *py_tuple = NULL; + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, "l", &pid)) + goto error; + + mib[0] = CTL_KERN; + mib[1] = KERN_LWP; + mib[2] = pid; + mib[3] = sizeof(struct kinfo_lwp); + mib[4] = 0; + + st = sysctl(mib, 5, NULL, &size, NULL, 0); + if (st == -1) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + if (size == 0) { + NoSuchProcess(); + goto error; + } + + mib[4] = size / sizeof(size_t); + kl = malloc(size); + if (kl == NULL) { + PyErr_NoMemory(); + goto error; + } + + st = sysctl(mib, 5, kl, &size, NULL, 0); + if (st == -1) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + if (size == 0) { + NoSuchProcess(); + goto error; + } + + nlwps = (int)(size / sizeof(struct kinfo_lwp)); + for (i = 0; i < nlwps; i++) { + py_tuple = Py_BuildValue("idd", + (&kl[i])->l_lid, + PSUTIL_KPT2DOUBLE((&kl[i])->l_rtime), + PSUTIL_KPT2DOUBLE((&kl[i])->l_rtime)); + if (py_tuple == NULL) + goto error; + if (PyList_Append(py_retlist, py_tuple)) + goto error; + Py_DECREF(py_tuple); + } + free(kl); + return py_retlist; + +error: + Py_XDECREF(py_tuple); + Py_DECREF(py_retlist); + if (kl != NULL) + free(kl); + return NULL; +} + +int +psutil_raise_ad_or_nsp(long pid) { + // Set exception to AccessDenied if pid exists else NoSuchProcess. + if (psutil_pid_exists(pid) == 0) + NoSuchProcess(); + else + AccessDenied(); +} + + +// ============================================================================ +// APIS +// ============================================================================ + +int +psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { + // Returns a list of all BSD processes on the system. This routine + // allocates the list and puts it in *procList and a count of the + // number of entries in *procCount. You are responsible for freeing + // this list (use "free" from System framework). + // On success, the function returns 0. + // On error, the function returns a BSD errno value. + kinfo_proc *result; + int done; + static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC, 0 }; + // Declaring name as const requires us to cast it when passing it to + // sysctl because the prototype doesn't include the const modifier. + size_t length; + char errbuf[_POSIX2_LINE_MAX]; + kinfo_proc *x; + int cnt; + kvm_t *kd; + + assert( procList != NULL); + assert(*procList == NULL); + assert(procCount != NULL); + + kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + + if (kd == NULL) { + return errno; + } + + result = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(kinfo_proc), &cnt); + if (result == NULL) { + err(1, NULL); + return errno; + } + + *procCount = (size_t)cnt; + + size_t mlen = cnt * sizeof(kinfo_proc); + + if ((*procList = malloc(mlen)) == NULL) { + err(1, NULL); + return errno; + } + + memcpy(*procList, result, mlen); + assert(*procList != NULL); + kvm_close(kd); + + return 0; +} + + +char * +psutil_get_cmd_args(pid_t pid, size_t *argsize) { + int mib[4]; + ssize_t st; + int argmax; + size_t size; + char *procargs = NULL; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARGMAX; + + size = sizeof(argmax); + st = sysctl(mib, 2, &argmax, &size, NULL, 0); + if (st == -1) + return NULL; + + procargs = (char *)malloc(argmax); + if (procargs == NULL) + return NULL; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = pid; + mib[3] = KERN_PROC_ARGV; + + st = sysctl(mib, 4, procargs, &argmax, NULL, 0); + if (st == -1) + return NULL; + + *argsize = argmax; + return procargs; +} + +// returns the command line as a python list object +PyObject * +psutil_get_cmdline(pid_t pid) { + char *argstr = NULL; + int pos = 0; + size_t argsize = 0; + PyObject *py_retlist = Py_BuildValue("[]"); + PyObject *py_arg = NULL; + + if (pid < 0) + return py_retlist; + argstr = psutil_get_cmd_args(pid, &argsize); + if (argstr == NULL) + goto error; + + // args are returned as a flattened string with \0 separators between + // arguments add each string to the list then step forward to the next + // separator + if (argsize > 0) { + while (pos < argsize) { + py_arg = Py_BuildValue("s", &argstr[pos]); + if (!py_arg) + goto error; + if (PyList_Append(py_retlist, py_arg)) + goto error; + Py_DECREF(py_arg); + pos = pos + strlen(&argstr[pos]) + 1; + } + } + + free(argstr); + return py_retlist; + +error: + Py_XDECREF(py_arg); + Py_DECREF(py_retlist); + if (argstr != NULL) + free(argstr); + return NULL; +} + + +PyObject * +psutil_virtual_mem(PyObject *self, PyObject *args) { + unsigned int total, active, inactive, wired, cached, free; + size_t size = sizeof(total); + struct uvmexp_sysctl uvmexp; + int mib[] = {CTL_VM, VM_UVMEXP2}; + long pagesize = getpagesize(); + size = sizeof(uvmexp); + + if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { + warn("failed to get vm.uvmexp"); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return Py_BuildValue("KKKKKKKK", + (unsigned long long) uvmexp.npages * pagesize, + (unsigned long long) uvmexp.free * pagesize, + (unsigned long long) uvmexp.active * pagesize, + (unsigned long long) uvmexp.inactive * pagesize, + (unsigned long long) uvmexp.wired * pagesize, + (unsigned long long) 0, + (unsigned long long) 0, + (unsigned long long) 0 + ); +} + + +PyObject * +psutil_swap_mem(PyObject *self, PyObject *args) { + uint64_t swap_total, swap_free; + struct swapent *swdev; + int nswap, i; + + if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) == 0) { + warn("failed to get swap device count"); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + if ((swdev = calloc(nswap, sizeof(*swdev))) == NULL) { + warn("failed to allocate memory for swdev structures"); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + if (swapctl(SWAP_STATS, swdev, nswap) == -1) { + free(swdev); + warn("failed to get swap stats"); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* Total things up */ + swap_total = swap_free = 0; + for (i = 0; i < nswap; i++) { + if (swdev[i].se_flags & SWF_ENABLE) { + swap_free += (swdev[i].se_nblks - swdev[i].se_inuse); + swap_total += swdev[i].se_nblks; + } + } + return Py_BuildValue("(LLLII)", + swap_total * DEV_BSIZE, + (swap_total - swap_free) * DEV_BSIZE, + swap_free * DEV_BSIZE, + 0 /* XXX swap in */, + 0 /* XXX swap out */); +} + + +PyObject * +psutil_proc_num_fds(PyObject *self, PyObject *args) { + long pid; + int cnt; + + struct kinfo_file *freep; + + if (! PyArg_ParseTuple(args, "l", &pid)) + 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); +} + + +PyObject * +psutil_proc_cwd(PyObject *self, PyObject *args) { + /* Not implemented */ + return NULL; +} + + +// see sys/kern/kern_sysctl.c lines 1100 and +// usr.bin/fstat/fstat.c print_inet_details() +static char * +psutil_convert_ipv4(int family, uint32_t addr[4]) { + struct in_addr a; + memcpy(&a, addr, sizeof(a)); + return inet_ntoa(a); +} + + +static char * +psutil_inet6_addrstr(struct in6_addr *p) +{ + struct sockaddr_in6 sin6; + static char hbuf[NI_MAXHOST]; + const int niflags = NI_NUMERICHOST; + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = *p; + if (IN6_IS_ADDR_LINKLOCAL(p) && + *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) { + sin6.sin6_scope_id = + ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); + sin6.sin6_addr.s6_addr[2] = sin6.sin6_addr.s6_addr[3] = 0; + } + + if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, + hbuf, sizeof(hbuf), NULL, 0, niflags)) + return "invalid"; + + return hbuf; +} + +PyObject * +psutil_per_cpu_times(PyObject *self, PyObject *args) { + static int maxcpus; + int mib[3]; + int ncpu; + size_t len; + size_t size; + int i; + PyObject *py_retlist = PyList_New(0); + PyObject *py_cputime = NULL; + + if (py_retlist == NULL) + return NULL; + + + // retrieve the number of cpus + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + len = sizeof(ncpu); + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + uint64_t cpu_time[CPUSTATES]; + + for (i = 0; i < ncpu; i++) { + // per-cpu info + mib[0] = CTL_KERN; + mib[1] = KERN_CP_TIME; + mib[2] = i; + size = sizeof(cpu_time); + if (sysctl(mib, 3, &cpu_time, &size, NULL, 0) == -1) { + warn("failed to get kern.cptime2"); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + py_cputime = Py_BuildValue( + "(ddddd)", + (double)cpu_time[CP_USER] / CLOCKS_PER_SEC, + (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC, + (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC, + (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC, + (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC); + if (!py_cputime) + goto error; + if (PyList_Append(py_retlist, py_cputime)) + goto error; + Py_DECREF(py_cputime); + } + + return py_retlist; + +error: + Py_XDECREF(py_cputime); + Py_DECREF(py_retlist); + return NULL; +} + + +PyObject * +psutil_disk_io_counters(PyObject *self, PyObject *args) { + int i, dk_ndrive, mib[3]; + size_t len; + struct io_sysctl *stats; + + PyObject *py_retdict = PyDict_New(); + PyObject *py_disk_info = NULL; + if (py_retdict == NULL) + return NULL; + + mib[0] = CTL_HW; + mib[1] = HW_IOSTATS; + mib[2] = sizeof(struct io_sysctl); + len = 0; + if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) { + warn("can't get HW_IOSTATS"); + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + dk_ndrive = (int)(len / sizeof(struct io_sysctl)); + + stats = malloc(len); + if (stats == NULL) { + warn("can't malloc"); + PyErr_NoMemory(); + goto error; + } + if (sysctl(mib, 2, stats, &len, NULL, 0) < 0 ) { + warn("could not read HW_IOSTATS"); + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + + for (i = 0; i < dk_ndrive; i++) { + py_disk_info = Py_BuildValue( + "(KKKKLL)", + stats[i].rxfer, + stats[i].wxfer, + stats[i].rbytes, + stats[i].wbytes, + // assume half read - half writes. + // TODO: why? + (long long) PSUTIL_KPT2DOUBLE(stats[i].time) / 2, + (long long) PSUTIL_KPT2DOUBLE(stats[i].time) / 2); + if (!py_disk_info) + goto error; + if (PyDict_SetItemString(py_retdict, stats[i].name, py_disk_info)) + goto error; + Py_DECREF(py_disk_info); + } + + free(stats); + return py_retdict; + +error: + Py_XDECREF(py_disk_info); + Py_DECREF(py_retdict); + if (stats != NULL) + free(stats); + return NULL; +} + diff --git a/psutil/arch/bsd/netbsd.h b/psutil/arch/bsd/netbsd.h new file mode 100644 index 000000000..71cca52e4 --- /dev/null +++ b/psutil/arch/bsd/netbsd.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2009, Giampaolo Rodola', Landry Breuil. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include + +typedef struct kinfo_proc2 kinfo_proc; + +int psutil_kinfo_proc(pid_t pid, kinfo_proc *proc); +struct kinfo_file * kinfo_getfile(pid_t pid, int* cnt); +int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount); +char *psutil_get_cmd_args(pid_t pid, size_t *argsize); +PyObject * psutil_get_cmdline(pid_t pid); +int psutil_pid_exists(pid_t pid); +int psutil_raise_ad_or_nsp(long pid); + +// +PyObject *psutil_proc_threads(PyObject *self, PyObject *args); +PyObject *psutil_virtual_mem(PyObject *self, PyObject *args); +PyObject *psutil_swap_mem(PyObject *self, PyObject *args); +PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args); +PyObject *psutil_proc_cwd(PyObject *self, PyObject *args); +PyObject *psutil_proc_connections(PyObject *self, PyObject *args); +PyObject *psutil_per_cpu_times(PyObject *self, PyObject *args); +PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args); +PyObject* psutil_proc_exe(PyObject* self, PyObject* args); +PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args); diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c new file mode 100644 index 000000000..12ae47435 --- /dev/null +++ b/psutil/arch/bsd/netbsd_socks.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2009, Giampaolo Rodola'. + * Copyright (c) 2015, Ryo ONODERA. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// a signaler for connections without an actual status +int PSUTIL_CONN_NONE = 128; + +/* Address family filter */ +enum af_filter { + INET, + INET4, + INET6, + TCP, + TCP4, + TCP6, + UDP, + UDP4, + UDP6, + UNIX, + ALL, +}; + +/* kinfo_file results */ +struct kif { + SLIST_ENTRY(kif) kifs; + struct kinfo_file *kif; +}; + +/* kinfo_file results list */ +SLIST_HEAD(kifhead, kif) kihead = SLIST_HEAD_INITIALIZER(kihead); + + +/* kinfo_pcb results */ +struct kpcb { + SLIST_ENTRY(kpcb) kpcbs; + struct kinfo_pcb *kpcb; +}; + +/* kinfo_pcb results list */ +SLIST_HEAD(kpcbhead, kpcb) kpcbhead = SLIST_HEAD_INITIALIZER(kpcbhead); + +static void kiflist_init(void); +static void kiflist_clear(void); +static void kpcblist_init(void); +static void kpcblist_clear(void); +static int get_files(void); +static int get_sockets(const char *name); +static void get_info(int aff); + +/* Initialize kinfo_file results list */ +static void +kiflist_init(void) +{ + SLIST_INIT(&kihead); + return; +} + +/* Clear kinfo_file results list */ +static void +kiflist_clear(void) +{ + while (!SLIST_EMPTY(&kihead)) { + SLIST_REMOVE_HEAD(&kihead, kifs); + } + + return; +} + +/* Initialize kinof_pcb result list */ +static void +kpcblist_init(void) +{ + SLIST_INIT(&kpcbhead); + return; +} + +/* Clear kinof_pcb result list */ +static void +kpcblist_clear(void) +{ + while (!SLIST_EMPTY(&kpcbhead)) { + SLIST_REMOVE_HEAD(&kpcbhead, kpcbs); + } + + return; +} + + +/* + * Get all open files including socket + */ +static int +get_files(void) +{ + size_t len; + int mib[6]; + char *buf; + off_t offset; + int j; + + mib[0] = CTL_KERN; + mib[1] = KERN_FILE2; + mib[2] = KERN_FILE_BYFILE; + mib[3] = 0; + mib[4] = sizeof(struct kinfo_file); + mib[5] = 0; + + if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) + return -1; + offset = len % sizeof(off_t); + mib[5] = len / sizeof(struct kinfo_file); + if ((buf = malloc(len + offset)) == NULL) + return -1; + if (sysctl(mib, 6, buf + offset, &len, NULL, 0) == -1) { + free(buf); + return -1; + } + + len /= sizeof(struct kinfo_file); + struct kinfo_file *ki = (struct kinfo_file *)(buf + offset); + + for (j = 0; j < len; j++) { + struct kif *kif = malloc(sizeof(struct kif)); + kif->kif = &ki[j]; + SLIST_INSERT_HEAD(&kihead, kif, kifs); + } + +#if 0 + /* debug */ + struct kif *k; + SLIST_FOREACH(k, &kihead, kifs) { + printf("%d\n", k->kif->ki_pid); + } +#endif + + return 0; +} + +/* + * Get open sockets + */ +static int +get_sockets(const char *name) +{ + size_t namelen; + int mib[8]; + int ret, j; + struct kinfo_pcb *pcb; + size_t len; + + memset(mib, 0, sizeof(mib)); + + if (sysctlnametomib(name, mib, &namelen) == -1) + return -1; + + if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) + return -1; + + if ((pcb = malloc(len)) == NULL) { + free(pcb); + return -1; + } + memset(pcb, 0, len); + + mib[6] = sizeof(*pcb); + mib[7] = len / sizeof(*pcb); + + if (sysctl(mib, __arraycount(mib), pcb, &len, NULL, 0) == -1) { + return -1; + } + + len /= sizeof(struct kinfo_pcb); + struct kinfo_pcb *kp = (struct kinfo_pcb *)pcb; + + for (j = 0; j < len; j++) { + struct kpcb *kpcb = malloc(sizeof(struct kpcb)); + kpcb->kpcb = &kp[j]; + SLIST_INSERT_HEAD(&kpcbhead, kpcb, kpcbs); + } + +#if 0 + /* debug */ + struct kif *k; + struct kpcb *k; + SLIST_FOREACH(k, &kpcbhead, kpcbs) { + printf("ki_type: %d\n", k->kpcb->ki_type); + printf("ki_family: %d\n", k->kpcb->ki_family); + } +#endif + + return 0; +} + + +/* + * Collect connections by PID + */ +PyObject * +psutil_proc_connections(PyObject *self, PyObject *args) +{ + PyObject *py_retlist = PyList_New(0); + PyObject *py_tuple = NULL; + PyObject *py_laddr = NULL; + PyObject *py_raddr = NULL; + pid_t pid; + + if (! PyArg_ParseTuple(args, "l", &pid)) + return NULL; + + if (py_retlist == NULL) + return NULL; + + kiflist_init(); + kpcblist_init(); + get_info(ALL); + + struct kif *k; + SLIST_FOREACH(k, &kihead, kifs) { + struct kpcb *kp; + if (k->kif->ki_pid == pid) { + SLIST_FOREACH(kp, &kpcbhead, kpcbs) { + if (k->kif->ki_fdata == kp->kpcb->ki_sockaddr) { + pid_t pid; + int32_t fd; + int32_t family; + int32_t type; + char laddr[PATH_MAX]; + int32_t lport; + char raddr[PATH_MAX]; + int32_t rport; + int32_t status; + + pid = k->kif->ki_pid; + fd = k->kif->ki_fd; + family = kp->kpcb->ki_family; + type = kp->kpcb->ki_type; + if (kp->kpcb->ki_family == AF_INET) { + struct sockaddr_in *sin_src = + (struct sockaddr_in *)&kp->kpcb->ki_src; + struct sockaddr_in *sin_dst = + (struct sockaddr_in *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET, &sin_src->sin_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin_src->sin_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin_dst->sin_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNi)", fd, AF_INET, + type, py_laddr, py_raddr, status); + if (!py_tuple) { + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_INET6) { + struct sockaddr_in6 *sin6_src = + (struct sockaddr_in6 *)&kp->kpcb->ki_src; + struct sockaddr_in6 *sin6_dst = + (struct sockaddr_in6 *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET6, &sin6_src->sin6_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin6_src->sin6_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin6_dst->sin6_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNi)", fd, AF_INET6, + type, py_laddr, py_raddr, status); + if (!py_tuple) { + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_UNIX) { + struct sockaddr_un *sun_src = + (struct sockaddr_un *)&kp->kpcb->ki_src; + struct sockaddr_un *sun_dst = + (struct sockaddr_un *)&kp->kpcb->ki_dst; + strcpy(laddr, sun_src->sun_path); + strcpy(raddr, sun_dst->sun_path); + status = PSUTIL_CONN_NONE; + + py_tuple = Py_BuildValue("(iiissi)", fd, AF_UNIX, + type, laddr, raddr, status); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_UNIX) { + struct sockaddr_un *sun_src = + (struct sockaddr_un *)&kp->kpcb->ki_src; + struct sockaddr_un *sun_dst = + (struct sockaddr_un *)&kp->kpcb->ki_dst; + strcpy(laddr, sun_src->sun_path); + strcpy(raddr, sun_dst->sun_path); + status = PSUTIL_CONN_NONE; + + py_tuple = Py_BuildValue("(iiissi)", fd, AF_UNIX, + type, laddr, raddr, status); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } + + + } + }} + } + + kiflist_clear(); + kpcblist_clear(); + return py_retlist; + + +} + + +/* + * Collect open file and connections + */ +static void +get_info(int aff) +{ + get_files(); + + switch (aff) { + case INET: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + break; + case INET4: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + break; + case INET6: + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + break; + case TCP: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet6.tcp6.pcblist"); + break; + case TCP4: + get_sockets("net.inet.tcp.pcblist"); + break; + case TCP6: + get_sockets("net.inet6.tcp6.pcblist"); + break; + case UDP: + get_sockets("net.inet.udp.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + break; + case UDP4: + get_sockets("net.inet.udp.pcblist"); + break; + case UDP6: + get_sockets("net.inet6.udp6.pcblist"); + break; + case UNIX: + get_sockets("net.local.stream.pcblist"); + get_sockets("net.local.seqpacket.pcblist"); + get_sockets("net.local.dgram.pcblist"); + break; + case ALL: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + get_sockets("net.local.stream.pcblist"); + get_sockets("net.local.seqpacket.pcblist"); + get_sockets("net.local.dgram.pcblist"); + break; + } + return; +} + +/* + * Collect system wide connections by address family filter + */ +PyObject * +psutil_net_connections(PyObject *self, PyObject *args) +{ + PyObject *py_retlist = PyList_New(0); + PyObject *py_tuple = NULL; + PyObject *py_laddr = NULL; + PyObject *py_raddr = NULL; + + if (py_retlist == NULL) + return NULL; + + kiflist_init(); + kpcblist_init(); + get_info(ALL); + + struct kif *k; + SLIST_FOREACH(k, &kihead, kifs) { + struct kpcb *kp; + SLIST_FOREACH(kp, &kpcbhead, kpcbs) { + if (k->kif->ki_fdata == kp->kpcb->ki_sockaddr) { + pid_t pid; + int32_t fd; + int32_t family; + int32_t type; + char laddr[PATH_MAX]; + int32_t lport; + char raddr[PATH_MAX]; + int32_t rport; + int32_t status; + + pid = k->kif->ki_pid; + fd = k->kif->ki_fd; + family = kp->kpcb->ki_family; + type = kp->kpcb->ki_type; + if (kp->kpcb->ki_family == AF_INET) { + struct sockaddr_in *sin_src = + (struct sockaddr_in *)&kp->kpcb->ki_src; + struct sockaddr_in *sin_dst = + (struct sockaddr_in *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET, &sin_src->sin_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin_src->sin_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin_dst->sin_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET, + type, py_laddr, py_raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_INET6) { + struct sockaddr_in6 *sin6_src = + (struct sockaddr_in6 *)&kp->kpcb->ki_src; + struct sockaddr_in6 *sin6_dst = + (struct sockaddr_in6 *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET6, &sin6_src->sin6_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin6_src->sin6_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin6_dst->sin6_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET6, + type, py_laddr, py_raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_UNIX) { + struct sockaddr_un *sun_src = + (struct sockaddr_un *)&kp->kpcb->ki_src; + struct sockaddr_un *sun_dst = + (struct sockaddr_un *)&kp->kpcb->ki_dst; + strcpy(laddr, sun_src->sun_path); + strcpy(raddr, sun_dst->sun_path); + status = PSUTIL_CONN_NONE; + + py_tuple = Py_BuildValue("(iiissii)", fd, AF_UNIX, + type, laddr, raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } + + + } + } + } + + kiflist_clear(); + kpcblist_clear(); + return py_retlist; +} diff --git a/psutil/arch/bsd/netbsd_socks.h b/psutil/arch/bsd/netbsd_socks.h new file mode 100644 index 000000000..9e6a97c0a --- /dev/null +++ b/psutil/arch/bsd/netbsd_socks.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2009, Giampaolo Rodola'. + * Copyright (c) 2015, Ryo ONODERA. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +PyObject *psutil_proc_connections(PyObject *, PyObject *); +PyObject *psutil_net_connections(PyObject *, PyObject *); diff --git a/setup.py b/setup.py index dd0b0c815..59f3a167f 100644 --- a/setup.py +++ b/setup.py @@ -151,6 +151,19 @@ def get_winver(): define_macros=[VERSION_MACRO], libraries=["kvm"]) extensions = [ext, posix_extension] +# NetBSD +elif sys.platform.startswith("netbsd"): + ext = Extension( + 'psutil._psutil_bsd', + sources=[ + 'psutil/_psutil_bsd.c', + 'psutil/_psutil_common.c', + 'psutil/arch/bsd/netbsd.c', + 'psutil/arch/bsd/netbsd_socks.c', + ], + define_macros=[VERSION_MACRO], + libraries=["kvm"]) + extensions = [ext, posix_extension] # Linux elif sys.platform.startswith("linux"): def get_ethtool_macro(): diff --git a/test/test_psutil.py b/test/test_psutil.py index d8c910abd..fba71d200 100644 --- a/test/test_psutil.py +++ b/test/test_psutil.py @@ -115,7 +115,8 @@ OSX = sys.platform.startswith("darwin") FREEBSD = sys.platform.startswith("freebsd") OPENBSD = sys.platform.startswith("openbsd") -BSD = FREEBSD or OPENBSD +NETBSD = sys.platform.startswith("netbsd") +BSD = FREEBSD or OPENBSD or NETBSD SUNOS = sys.platform.startswith("sunos") VALID_PROC_STATUSES = [getattr(psutil, x) for x in dir(psutil) if x.startswith('STATUS_')] From 410a28cb19cd0d879f82a5a1660d08c3abe80483 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:14:28 +0100 Subject: [PATCH 02/26] Fix line length (PEP8). --- psutil/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index e30645aa9..2ab1b7f2b 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -123,7 +123,8 @@ elif sys.platform.startswith("darwin"): from . import _psosx as _psplatform -elif sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd") or sys.platform.startswith("netbsd"): +elif sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd") \ + or sys.platform.startswith("netbsd"): from . import _psbsd as _psplatform elif sys.platform.startswith("sunos"): From aafe03b9ad9bc75674aa644648680c3b75312c65 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:20:45 +0100 Subject: [PATCH 03/26] Return PyErr_NoMemory(); on out-of-memory. --- psutil/arch/bsd/netbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 4bc30a2a5..03aa094a7 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -97,7 +97,7 @@ kinfo_getfile(pid_t pid, int* cnt) { return NULL; } if ((kf = malloc(len)) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); + PyErr_NoMemory(); return NULL; } mib[5] = (int)(len / sizeof(struct kinfo_file)); From 060d806f189475558bd50292738ee530a4bcd929 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:22:52 +0100 Subject: [PATCH 04/26] Return empty string when guessing pathname fails. --- psutil/arch/bsd/netbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 03aa094a7..4f65e6c95 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -176,7 +176,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) { } return Py_BuildValue("s", pathname); #else - return NULL; + return Py_BuildValue("s", ""); #endif } From 7911853e10bc5f5acaabeb69221b799137755375 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:24:46 +0100 Subject: [PATCH 05/26] Move function on request from giampaolo. --- psutil/arch/bsd/netbsd.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 4f65e6c95..91ecb665c 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -49,6 +49,17 @@ // Utility functions // ============================================================================ + +int +psutil_raise_ad_or_nsp(long pid) { + // Set exception to AccessDenied if pid exists else NoSuchProcess. + if (psutil_pid_exists(pid) == 0) + NoSuchProcess(); + else + AccessDenied(); +} + + int psutil_kinfo_proc(pid_t pid, kinfo_proc *proc) { // Fills a kinfo_proc struct based on process pid. @@ -264,15 +275,6 @@ psutil_proc_threads(PyObject *self, PyObject *args) { return NULL; } -int -psutil_raise_ad_or_nsp(long pid) { - // Set exception to AccessDenied if pid exists else NoSuchProcess. - if (psutil_pid_exists(pid) == 0) - NoSuchProcess(); - else - AccessDenied(); -} - // ============================================================================ // APIS From de9d7632244dcbe59191fec49c1b1918469cc7e8 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:28:57 +0100 Subject: [PATCH 06/26] Call kvm_close() in error cases to avoid resource leak. --- psutil/arch/bsd/netbsd.c | 2 ++ psutil/arch/bsd/openbsd.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 91ecb665c..308b54843 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -311,6 +311,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { result = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(kinfo_proc), &cnt); if (result == NULL) { + kvm_close(kd); err(1, NULL); return errno; } @@ -320,6 +321,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { size_t mlen = cnt * sizeof(kinfo_proc); if ((*procList = malloc(mlen)) == NULL) { + kvm_close(kd); err(1, NULL); return errno; } diff --git a/psutil/arch/bsd/openbsd.c b/psutil/arch/bsd/openbsd.c index 82a598d15..24a05524e 100644 --- a/psutil/arch/bsd/openbsd.c +++ b/psutil/arch/bsd/openbsd.c @@ -178,6 +178,7 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { result = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cnt); if (result == NULL) { + kvm_close(kd); err(1, NULL); return errno; } @@ -187,6 +188,7 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { size_t mlen = cnt * sizeof(struct kinfo_proc); if ((*procList = malloc(mlen)) == NULL) { + kvm_close(kd); err(1, NULL); return errno; } From c81dcf52c6d956e39c7bef2d8011c7077e5b4dff Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:29:16 +0100 Subject: [PATCH 07/26] untabify --- psutil/arch/bsd/netbsd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 308b54843..ed6ecf67e 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -348,11 +348,11 @@ psutil_get_cmd_args(pid_t pid, size_t *argsize) { size = sizeof(argmax); st = sysctl(mib, 2, &argmax, &size, NULL, 0); if (st == -1) - return NULL; + return NULL; procargs = (char *)malloc(argmax); if (procargs == NULL) - return NULL; + return NULL; mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; @@ -361,7 +361,7 @@ psutil_get_cmd_args(pid_t pid, size_t *argsize) { st = sysctl(mib, 4, procargs, &argmax, NULL, 0); if (st == -1) - return NULL; + return NULL; *argsize = argmax; return procargs; From 15e4eef37e9460503be6bc871587acaa17c38d22 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:32:32 +0100 Subject: [PATCH 08/26] untabify --- psutil/arch/bsd/netbsd_socks.c | 256 ++++++++++++++++----------------- 1 file changed, 128 insertions(+), 128 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index 12ae47435..5775b2a66 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -138,9 +138,9 @@ get_files(void) struct kinfo_file *ki = (struct kinfo_file *)(buf + offset); for (j = 0; j < len; j++) { - struct kif *kif = malloc(sizeof(struct kif)); - kif->kif = &ki[j]; - SLIST_INSERT_HEAD(&kihead, kif, kifs); + struct kif *kif = malloc(sizeof(struct kif)); + kif->kif = &ki[j]; + SLIST_INSERT_HEAD(&kihead, kif, kifs); } #if 0 @@ -172,11 +172,11 @@ get_sockets(const char *name) return -1; if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) - return -1; + return -1; if ((pcb = malloc(len)) == NULL) { - free(pcb); - return -1; + free(pcb); + return -1; } memset(pcb, 0, len); @@ -184,7 +184,7 @@ get_sockets(const char *name) mib[7] = len / sizeof(*pcb); if (sysctl(mib, __arraycount(mib), pcb, &len, NULL, 0) == -1) { - return -1; + return -1; } len /= sizeof(struct kinfo_pcb); @@ -362,29 +362,29 @@ get_info(int aff) get_files(); switch (aff) { - case INET: - get_sockets("net.inet.tcp.pcblist"); - get_sockets("net.inet.udp.pcblist"); - get_sockets("net.inet6.tcp6.pcblist"); - get_sockets("net.inet6.udp6.pcblist"); - break; - case INET4: - get_sockets("net.inet.tcp.pcblist"); - get_sockets("net.inet.udp.pcblist"); - break; - case INET6: - get_sockets("net.inet6.tcp6.pcblist"); - get_sockets("net.inet6.udp6.pcblist"); - break; - case TCP: + case INET: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + break; + case INET4: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + break; + case INET6: + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + break; + case TCP: get_sockets("net.inet.tcp.pcblist"); get_sockets("net.inet6.tcp6.pcblist"); - break; - case TCP4: + break; + case TCP4: get_sockets("net.inet.tcp.pcblist"); break; - case TCP6: - get_sockets("net.inet6.tcp6.pcblist"); + case TCP6: + get_sockets("net.inet6.tcp6.pcblist"); break; case UDP: get_sockets("net.inet.udp.pcblist"); @@ -397,19 +397,19 @@ get_info(int aff) get_sockets("net.inet6.udp6.pcblist"); break; case UNIX: - get_sockets("net.local.stream.pcblist"); - get_sockets("net.local.seqpacket.pcblist"); - get_sockets("net.local.dgram.pcblist"); + get_sockets("net.local.stream.pcblist"); + get_sockets("net.local.seqpacket.pcblist"); + get_sockets("net.local.dgram.pcblist"); + break; + case ALL: + get_sockets("net.inet.tcp.pcblist"); + get_sockets("net.inet.udp.pcblist"); + get_sockets("net.inet6.tcp6.pcblist"); + get_sockets("net.inet6.udp6.pcblist"); + get_sockets("net.local.stream.pcblist"); + get_sockets("net.local.seqpacket.pcblist"); + get_sockets("net.local.dgram.pcblist"); break; - case ALL: - get_sockets("net.inet.tcp.pcblist"); - get_sockets("net.inet.udp.pcblist"); - get_sockets("net.inet6.tcp6.pcblist"); - get_sockets("net.inet6.udp6.pcblist"); - get_sockets("net.local.stream.pcblist"); - get_sockets("net.local.seqpacket.pcblist"); - get_sockets("net.local.dgram.pcblist"); - break; } return; } @@ -437,96 +437,96 @@ psutil_net_connections(PyObject *self, PyObject *args) struct kpcb *kp; SLIST_FOREACH(kp, &kpcbhead, kpcbs) { if (k->kif->ki_fdata == kp->kpcb->ki_sockaddr) { - pid_t pid; - int32_t fd; - int32_t family; - int32_t type; - char laddr[PATH_MAX]; - int32_t lport; - char raddr[PATH_MAX]; - int32_t rport; - int32_t status; - - pid = k->kif->ki_pid; - fd = k->kif->ki_fd; - family = kp->kpcb->ki_family; - type = kp->kpcb->ki_type; - if (kp->kpcb->ki_family == AF_INET) { - struct sockaddr_in *sin_src = - (struct sockaddr_in *)&kp->kpcb->ki_src; - struct sockaddr_in *sin_dst = - (struct sockaddr_in *)&kp->kpcb->ki_dst; - if (inet_ntop(AF_INET, &sin_src->sin_addr, laddr, - sizeof(laddr)) != NULL) - lport = ntohs(sin_src->sin_port); - py_laddr = Py_BuildValue("(si)", laddr, lport); - if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, - sizeof(raddr)) != NULL) - rport = ntohs(sin_dst->sin_port); - py_raddr = Py_BuildValue("(si)", raddr, rport); - if (kp->kpcb->ki_type == SOCK_STREAM) { - status = kp->kpcb->ki_tstate; - } else { - status = PSUTIL_CONN_NONE; - } - - py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET, - type, py_laddr, py_raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } - if (PyList_Append(py_retlist, py_tuple)) - return 0; - } else if (kp->kpcb->ki_family == AF_INET6) { - struct sockaddr_in6 *sin6_src = - (struct sockaddr_in6 *)&kp->kpcb->ki_src; - struct sockaddr_in6 *sin6_dst = - (struct sockaddr_in6 *)&kp->kpcb->ki_dst; - if (inet_ntop(AF_INET6, &sin6_src->sin6_addr, laddr, - sizeof(laddr)) != NULL) - lport = ntohs(sin6_src->sin6_port); - py_laddr = Py_BuildValue("(si)", laddr, lport); - if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, - sizeof(raddr)) != NULL) - rport = ntohs(sin6_dst->sin6_port); - py_raddr = Py_BuildValue("(si)", raddr, rport); - if (kp->kpcb->ki_type == SOCK_STREAM) { - status = kp->kpcb->ki_tstate; - } else { - status = PSUTIL_CONN_NONE; - } - - py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET6, - type, py_laddr, py_raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } - if (PyList_Append(py_retlist, py_tuple)) - return 0; - } else if (kp->kpcb->ki_family == AF_UNIX) { - struct sockaddr_un *sun_src = - (struct sockaddr_un *)&kp->kpcb->ki_src; - struct sockaddr_un *sun_dst = - (struct sockaddr_un *)&kp->kpcb->ki_dst; - strcpy(laddr, sun_src->sun_path); - strcpy(raddr, sun_dst->sun_path); - status = PSUTIL_CONN_NONE; - - py_tuple = Py_BuildValue("(iiissii)", fd, AF_UNIX, - type, laddr, raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } - if (PyList_Append(py_retlist, py_tuple)) - return 0; - } - - - } - } + pid_t pid; + int32_t fd; + int32_t family; + int32_t type; + char laddr[PATH_MAX]; + int32_t lport; + char raddr[PATH_MAX]; + int32_t rport; + int32_t status; + + pid = k->kif->ki_pid; + fd = k->kif->ki_fd; + family = kp->kpcb->ki_family; + type = kp->kpcb->ki_type; + if (kp->kpcb->ki_family == AF_INET) { + struct sockaddr_in *sin_src = + (struct sockaddr_in *)&kp->kpcb->ki_src; + struct sockaddr_in *sin_dst = + (struct sockaddr_in *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET, &sin_src->sin_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin_src->sin_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin_dst->sin_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET, + type, py_laddr, py_raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_INET6) { + struct sockaddr_in6 *sin6_src = + (struct sockaddr_in6 *)&kp->kpcb->ki_src; + struct sockaddr_in6 *sin6_dst = + (struct sockaddr_in6 *)&kp->kpcb->ki_dst; + if (inet_ntop(AF_INET6, &sin6_src->sin6_addr, laddr, + sizeof(laddr)) != NULL) + lport = ntohs(sin6_src->sin6_port); + py_laddr = Py_BuildValue("(si)", laddr, lport); + if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, + sizeof(raddr)) != NULL) + rport = ntohs(sin6_dst->sin6_port); + py_raddr = Py_BuildValue("(si)", raddr, rport); + if (kp->kpcb->ki_type == SOCK_STREAM) { + status = kp->kpcb->ki_tstate; + } else { + status = PSUTIL_CONN_NONE; + } + + py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET6, + type, py_laddr, py_raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } else if (kp->kpcb->ki_family == AF_UNIX) { + struct sockaddr_un *sun_src = + (struct sockaddr_un *)&kp->kpcb->ki_src; + struct sockaddr_un *sun_dst = + (struct sockaddr_un *)&kp->kpcb->ki_dst; + strcpy(laddr, sun_src->sun_path); + strcpy(raddr, sun_dst->sun_path); + status = PSUTIL_CONN_NONE; + + py_tuple = Py_BuildValue("(iiissii)", fd, AF_UNIX, + type, laddr, raddr, status, pid); + if (!py_tuple) { + printf("Empty tuple\n"); + return 0; + } + if (PyList_Append(py_retlist, py_tuple)) + return 0; + } + + + } + } } kiflist_clear(); From 968bd9dc6aee5b4b844d5c9fe58bd1bd3ffb6b30 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:35:00 +0100 Subject: [PATCH 09/26] Use // for single-line comments. --- psutil/arch/bsd/netbsd_socks.c | 42 +++++++++++++--------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index 5775b2a66..b19cde3fe 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -23,7 +23,7 @@ // a signaler for connections without an actual status int PSUTIL_CONN_NONE = 128; -/* Address family filter */ +// Address family filter enum af_filter { INET, INET4, @@ -38,23 +38,23 @@ enum af_filter { ALL, }; -/* kinfo_file results */ +// kinfo_file results struct kif { SLIST_ENTRY(kif) kifs; struct kinfo_file *kif; }; -/* kinfo_file results list */ +// kinfo_file results list SLIST_HEAD(kifhead, kif) kihead = SLIST_HEAD_INITIALIZER(kihead); -/* kinfo_pcb results */ +// kinfo_pcb results struct kpcb { SLIST_ENTRY(kpcb) kpcbs; struct kinfo_pcb *kpcb; }; -/* kinfo_pcb results list */ +// kinfo_pcb results list SLIST_HEAD(kpcbhead, kpcb) kpcbhead = SLIST_HEAD_INITIALIZER(kpcbhead); static void kiflist_init(void); @@ -65,7 +65,7 @@ static int get_files(void); static int get_sockets(const char *name); static void get_info(int aff); -/* Initialize kinfo_file results list */ +// Initialize kinfo_file results list static void kiflist_init(void) { @@ -73,7 +73,7 @@ kiflist_init(void) return; } -/* Clear kinfo_file results list */ +// Clear kinfo_file results list static void kiflist_clear(void) { @@ -84,7 +84,7 @@ kiflist_clear(void) return; } -/* Initialize kinof_pcb result list */ +// Initialize kinof_pcb result list static void kpcblist_init(void) { @@ -92,7 +92,7 @@ kpcblist_init(void) return; } -/* Clear kinof_pcb result list */ +// Clear kinof_pcb result list static void kpcblist_clear(void) { @@ -104,9 +104,7 @@ kpcblist_clear(void) } -/* - * Get all open files including socket - */ +// Get all open files including socket static int get_files(void) { @@ -144,7 +142,7 @@ get_files(void) } #if 0 - /* debug */ + // debug struct kif *k; SLIST_FOREACH(k, &kihead, kifs) { printf("%d\n", k->kif->ki_pid); @@ -154,9 +152,7 @@ get_files(void) return 0; } -/* - * Get open sockets - */ +// Get open sockets static int get_sockets(const char *name) { @@ -197,7 +193,7 @@ get_sockets(const char *name) } #if 0 - /* debug */ + // debug struct kif *k; struct kpcb *k; SLIST_FOREACH(k, &kpcbhead, kpcbs) { @@ -210,9 +206,7 @@ get_sockets(const char *name) } -/* - * Collect connections by PID - */ +// Collect connections by PID PyObject * psutil_proc_connections(PyObject *self, PyObject *args) { @@ -353,9 +347,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) } -/* - * Collect open file and connections - */ +// Collect open file and connections static void get_info(int aff) { @@ -414,9 +406,7 @@ get_info(int aff) return; } -/* - * Collect system wide connections by address family filter - */ +// Collect system wide connections by address family filter PyObject * psutil_net_connections(PyObject *self, PyObject *args) { From ff5b73111de192593192e765dd7935b93308d431 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:36:57 +0100 Subject: [PATCH 10/26] Use // for single-line comments. --- psutil/arch/bsd/netbsd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index ed6ecf67e..7192c6228 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -102,7 +102,7 @@ kinfo_getfile(pid_t pid, int* cnt) { mib[4] = sizeof(struct kinfo_file); mib[5] = 0; - /* get the size of what would be returned */ + // get the size of what would be returned if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -461,7 +461,7 @@ psutil_swap_mem(PyObject *self, PyObject *args) { return NULL; } - /* Total things up */ + // Total things up swap_total = swap_free = 0; for (i = 0; i < nswap; i++) { if (swdev[i].se_flags & SWF_ENABLE) { @@ -473,8 +473,8 @@ psutil_swap_mem(PyObject *self, PyObject *args) { swap_total * DEV_BSIZE, (swap_total - swap_free) * DEV_BSIZE, swap_free * DEV_BSIZE, - 0 /* XXX swap in */, - 0 /* XXX swap out */); + 0, // XXX swap in + 0); // XXX swap out } @@ -501,7 +501,7 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) { PyObject * psutil_proc_cwd(PyObject *self, PyObject *args) { - /* Not implemented */ + // Not implemented return NULL; } From 34c2110ff327a9e1e878237886ba3f637fd0530b Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:38:24 +0100 Subject: [PATCH 11/26] style: move opening brace to end of line --- psutil/arch/bsd/netbsd.c | 3 +-- psutil/arch/bsd/netbsd_socks.c | 27 +++++++++------------------ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 7192c6228..2c1391568 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -517,8 +517,7 @@ psutil_convert_ipv4(int family, uint32_t addr[4]) { static char * -psutil_inet6_addrstr(struct in6_addr *p) -{ +psutil_inet6_addrstr(struct in6_addr *p) { struct sockaddr_in6 sin6; static char hbuf[NI_MAXHOST]; const int niflags = NI_NUMERICHOST; diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index b19cde3fe..2ff5b1e2b 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -67,16 +67,14 @@ static void get_info(int aff); // Initialize kinfo_file results list static void -kiflist_init(void) -{ +kiflist_init(void) { SLIST_INIT(&kihead); return; } // Clear kinfo_file results list static void -kiflist_clear(void) -{ +kiflist_clear(void) { while (!SLIST_EMPTY(&kihead)) { SLIST_REMOVE_HEAD(&kihead, kifs); } @@ -86,16 +84,14 @@ kiflist_clear(void) // Initialize kinof_pcb result list static void -kpcblist_init(void) -{ +kpcblist_init(void) { SLIST_INIT(&kpcbhead); return; } // Clear kinof_pcb result list static void -kpcblist_clear(void) -{ +kpcblist_clear(void) { while (!SLIST_EMPTY(&kpcbhead)) { SLIST_REMOVE_HEAD(&kpcbhead, kpcbs); } @@ -106,8 +102,7 @@ kpcblist_clear(void) // Get all open files including socket static int -get_files(void) -{ +get_files(void) { size_t len; int mib[6]; char *buf; @@ -154,8 +149,7 @@ get_files(void) // Get open sockets static int -get_sockets(const char *name) -{ +get_sockets(const char *name) { size_t namelen; int mib[8]; int ret, j; @@ -208,8 +202,7 @@ get_sockets(const char *name) // Collect connections by PID PyObject * -psutil_proc_connections(PyObject *self, PyObject *args) -{ +psutil_proc_connections(PyObject *self, PyObject *args) { PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; PyObject *py_laddr = NULL; @@ -349,8 +342,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) // Collect open file and connections static void -get_info(int aff) -{ +get_info(int aff) { get_files(); switch (aff) { @@ -408,8 +400,7 @@ get_info(int aff) // Collect system wide connections by address family filter PyObject * -psutil_net_connections(PyObject *self, PyObject *args) -{ +psutil_net_connections(PyObject *self, PyObject *args) { PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; PyObject *py_laddr = NULL; From 72fd357a5d75c3bc41a0f7bb61191e5cd336059f Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:43:58 +0100 Subject: [PATCH 12/26] Use PyList_New instead of Py_BuildValue("[]") XXX: other backends also could be changed for this --- psutil/arch/bsd/netbsd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 2c1391568..ee3085240 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -373,8 +373,10 @@ psutil_get_cmdline(pid_t pid) { char *argstr = NULL; int pos = 0; size_t argsize = 0; - PyObject *py_retlist = Py_BuildValue("[]"); PyObject *py_arg = NULL; + PyObject *py_retlist = PyList_New(0); + if (py_retlist == NULL) + return NULL; if (pid < 0) return py_retlist; From 8b4388bd94bbd9b241358c143917222db4f6480c Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:45:01 +0100 Subject: [PATCH 13/26] Remove trailing whitespace. --- psutil/arch/bsd/netbsd_socks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index 2ff5b1e2b..3076e1c81 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -43,7 +43,7 @@ struct kif { SLIST_ENTRY(kif) kifs; struct kinfo_file *kif; }; - + // kinfo_file results list SLIST_HEAD(kifhead, kif) kihead = SLIST_HEAD_INITIALIZER(kihead); @@ -338,7 +338,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) { } - + // Collect open file and connections static void From 6d76d3452aba0a53de5297369a367ac78f64f7aa Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:46:01 +0100 Subject: [PATCH 14/26] Remove unnecessary pid check. --- psutil/arch/bsd/netbsd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index ee3085240..c362e6410 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -378,8 +378,6 @@ psutil_get_cmdline(pid_t pid) { if (py_retlist == NULL) return NULL; - if (pid < 0) - return py_retlist; argstr = psutil_get_cmd_args(pid, &argsize); if (argstr == NULL) goto error; From 3b8aeba8428d528363046d9f177ea6ab6d55060c Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:47:11 +0100 Subject: [PATCH 15/26] Remove unnecessary whitespace. --- psutil/arch/bsd/netbsd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index c362e6410..fd9e7290c 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -424,11 +424,11 @@ psutil_virtual_mem(PyObject *self, PyObject *args) { return NULL; } return Py_BuildValue("KKKKKKKK", - (unsigned long long) uvmexp.npages * pagesize, - (unsigned long long) uvmexp.free * pagesize, - (unsigned long long) uvmexp.active * pagesize, + (unsigned long long) uvmexp.npages * pagesize, + (unsigned long long) uvmexp.free * pagesize, + (unsigned long long) uvmexp.active * pagesize, (unsigned long long) uvmexp.inactive * pagesize, - (unsigned long long) uvmexp.wired * pagesize, + (unsigned long long) uvmexp.wired * pagesize, (unsigned long long) 0, (unsigned long long) 0, (unsigned long long) 0 From 2d377cd23a88dc3799c0ed50e7b2714f1bf2172f Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 12:48:04 +0100 Subject: [PATCH 16/26] Remove unnecessary whitespace. --- psutil/arch/bsd/netbsd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index fd9e7290c..b4eea6aa5 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -293,7 +293,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC, 0 }; // Declaring name as const requires us to cast it when passing it to // sysctl because the prototype doesn't include the const modifier. - size_t length; + size_t length; char errbuf[_POSIX2_LINE_MAX]; kinfo_proc *x; int cnt; @@ -411,11 +411,11 @@ psutil_get_cmdline(pid_t pid) { PyObject * psutil_virtual_mem(PyObject *self, PyObject *args) { - unsigned int total, active, inactive, wired, cached, free; - size_t size = sizeof(total); + unsigned int total, active, inactive, wired, cached, free; + size_t size = sizeof(total); struct uvmexp_sysctl uvmexp; - int mib[] = {CTL_VM, VM_UVMEXP2}; - long pagesize = getpagesize(); + int mib[] = {CTL_VM, VM_UVMEXP2}; + long pagesize = getpagesize(); size = sizeof(uvmexp); if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { From 59fbfa601ca1c0baf2ff70345964bd06c6edbc11 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 13:21:35 +0100 Subject: [PATCH 17/26] Raise more exceptions. --- psutil/arch/bsd/netbsd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index b4eea6aa5..2e95ab5fb 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -306,13 +306,14 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); if (kd == NULL) { + PyErr_Format(PyExc_RuntimeError, "kvm_openfiles() failed: %s", errbuf); return errno; } result = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(kinfo_proc), &cnt); if (result == NULL) { + PyErr_Format(PyExc_RuntimeError, "kvm_getproc2() failed"); kvm_close(kd); - err(1, NULL); return errno; } @@ -321,8 +322,8 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { size_t mlen = cnt * sizeof(kinfo_proc); if ((*procList = malloc(mlen)) == NULL) { + PyErr_NoMemory(); kvm_close(kd); - err(1, NULL); return errno; } From d95d720bf2736d949749ab30b7a230f2d0dd6ee3 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 13:50:54 +0100 Subject: [PATCH 18/26] Initialize pointer so that free() does not free random memory addresses. --- psutil/arch/bsd/netbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 2e95ab5fb..a77420809 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -210,7 +210,7 @@ psutil_proc_threads(PyObject *self, PyObject *args) { int i, nlwps; ssize_t st; size_t size; - struct kinfo_lwp *kl; + struct kinfo_lwp *kl = NULL; PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; From e867d783408839227e9ca85f27e2c3915b688686 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 18:01:06 +0100 Subject: [PATCH 19/26] Return exceptions in more cases. --- psutil/arch/bsd/netbsd.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index a77420809..1c3833a26 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -348,12 +348,17 @@ psutil_get_cmd_args(pid_t pid, size_t *argsize) { size = sizeof(argmax); st = sysctl(mib, 2, &argmax, &size, NULL, 0); - if (st == -1) + if (st == -1) { + warn("failed to get kern.argmax"); + PyErr_SetFromErrno(PyExc_OSError); return NULL; + } procargs = (char *)malloc(argmax); - if (procargs == NULL) + if (procargs == NULL) { + PyErr_NoMemory(); return NULL; + } mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; @@ -361,8 +366,11 @@ psutil_get_cmd_args(pid_t pid, size_t *argsize) { mib[3] = KERN_PROC_ARGV; st = sysctl(mib, 4, procargs, &argmax, NULL, 0); - if (st == -1) + if (st == -1) { + warn("failed to get kern.procargs"); + PyErr_SetFromErrno(PyExc_OSError); return NULL; + } *argsize = argmax; return procargs; From 7178b30e487096c641955a339784439efb555fb8 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Wed, 30 Dec 2015 18:02:57 +0100 Subject: [PATCH 20/26] Add missing free(). --- psutil/arch/bsd/netbsd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 1c3833a26..80fc7be75 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -478,6 +478,7 @@ psutil_swap_mem(PyObject *self, PyObject *args) { swap_total += swdev[i].se_nblks; } } + free(swdev); return Py_BuildValue("(LLLII)", swap_total * DEV_BSIZE, (swap_total - swap_free) * DEV_BSIZE, From 319b4aa6ae1610004bd50999e0c9985e12ba17d5 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Thu, 31 Dec 2015 07:45:19 +0100 Subject: [PATCH 21/26] Move free() to correct place. Avoids reference leak. --- psutil/arch/bsd/netbsd_socks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index 3076e1c81..edb4e299b 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -165,7 +165,6 @@ get_sockets(const char *name) { return -1; if ((pcb = malloc(len)) == NULL) { - free(pcb); return -1; } memset(pcb, 0, len); @@ -174,6 +173,7 @@ get_sockets(const char *name) { mib[7] = len / sizeof(*pcb); if (sysctl(mib, __arraycount(mib), pcb, &len, NULL, 0) == -1) { + free(pcb); return -1; } From 0d532f82275f65caa71e3b0ce2a1be360212307e Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Thu, 31 Dec 2015 19:26:21 +0100 Subject: [PATCH 22/26] Remove duplicate case statement. --- psutil/arch/bsd/netbsd_socks.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index edb4e299b..ec8b74f20 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -300,23 +300,6 @@ psutil_proc_connections(PyObject *self, PyObject *args) { strcpy(raddr, sun_dst->sun_path); status = PSUTIL_CONN_NONE; - py_tuple = Py_BuildValue("(iiissi)", fd, AF_UNIX, - type, laddr, raddr, status); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } - if (PyList_Append(py_retlist, py_tuple)) - return 0; - } else if (kp->kpcb->ki_family == AF_UNIX) { - struct sockaddr_un *sun_src = - (struct sockaddr_un *)&kp->kpcb->ki_src; - struct sockaddr_un *sun_dst = - (struct sockaddr_un *)&kp->kpcb->ki_dst; - strcpy(laddr, sun_src->sun_path); - strcpy(raddr, sun_dst->sun_path); - status = PSUTIL_CONN_NONE; - py_tuple = Py_BuildValue("(iiissi)", fd, AF_UNIX, type, laddr, raddr, status); if (!py_tuple) { From db60ef7f12576f711d5a9613464968ce367bb8a4 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Thu, 31 Dec 2015 19:42:54 +0100 Subject: [PATCH 23/26] Improve reference counting. --- psutil/arch/bsd/netbsd_socks.c | 74 +++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index ec8b74f20..00070af86 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -248,10 +248,14 @@ psutil_proc_connections(PyObject *self, PyObject *args) { sizeof(laddr)) != NULL) lport = ntohs(sin_src->sin_port); py_laddr = Py_BuildValue("(si)", laddr, lport); + if (!py_laddr) + goto error; if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, sizeof(raddr)) != NULL) rport = ntohs(sin_dst->sin_port); py_raddr = Py_BuildValue("(si)", raddr, rport); + if (!py_raddr) + goto error; if (kp->kpcb->ki_type == SOCK_STREAM) { status = kp->kpcb->ki_tstate; } else { @@ -260,11 +264,10 @@ psutil_proc_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiiNNi)", fd, AF_INET, type, py_laddr, py_raddr, status); - if (!py_tuple) { - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } else if (kp->kpcb->ki_family == AF_INET6) { struct sockaddr_in6 *sin6_src = (struct sockaddr_in6 *)&kp->kpcb->ki_src; @@ -274,10 +277,14 @@ psutil_proc_connections(PyObject *self, PyObject *args) { sizeof(laddr)) != NULL) lport = ntohs(sin6_src->sin6_port); py_laddr = Py_BuildValue("(si)", laddr, lport); + if (!py_laddr) + goto error; if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, sizeof(raddr)) != NULL) rport = ntohs(sin6_dst->sin6_port); py_raddr = Py_BuildValue("(si)", raddr, rport); + if (!py_raddr) + goto error; if (kp->kpcb->ki_type == SOCK_STREAM) { status = kp->kpcb->ki_tstate; } else { @@ -286,11 +293,10 @@ psutil_proc_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiiNNi)", fd, AF_INET6, type, py_laddr, py_raddr, status); - if (!py_tuple) { - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } else if (kp->kpcb->ki_family == AF_UNIX) { struct sockaddr_un *sun_src = (struct sockaddr_un *)&kp->kpcb->ki_src; @@ -302,12 +308,10 @@ psutil_proc_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiissi)", fd, AF_UNIX, type, laddr, raddr, status); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } @@ -319,7 +323,11 @@ psutil_proc_connections(PyObject *self, PyObject *args) { kpcblist_clear(); return py_retlist; - +error: + Py_XDECREF(py_tuple); + Py_XDECREF(py_laddr); + Py_XDECREF(py_raddr); + return 0; } @@ -424,10 +432,14 @@ psutil_net_connections(PyObject *self, PyObject *args) { sizeof(laddr)) != NULL) lport = ntohs(sin_src->sin_port); py_laddr = Py_BuildValue("(si)", laddr, lport); + if (!py_laddr) + goto error; if (inet_ntop(AF_INET, &sin_dst->sin_addr, raddr, sizeof(raddr)) != NULL) rport = ntohs(sin_dst->sin_port); py_raddr = Py_BuildValue("(si)", raddr, rport); + if (!py_raddr) + goto error; if (kp->kpcb->ki_type == SOCK_STREAM) { status = kp->kpcb->ki_tstate; } else { @@ -436,12 +448,10 @@ psutil_net_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET, type, py_laddr, py_raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } else if (kp->kpcb->ki_family == AF_INET6) { struct sockaddr_in6 *sin6_src = (struct sockaddr_in6 *)&kp->kpcb->ki_src; @@ -451,10 +461,14 @@ psutil_net_connections(PyObject *self, PyObject *args) { sizeof(laddr)) != NULL) lport = ntohs(sin6_src->sin6_port); py_laddr = Py_BuildValue("(si)", laddr, lport); + if (!py_laddr) + goto error; if (inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr, sizeof(raddr)) != NULL) rport = ntohs(sin6_dst->sin6_port); py_raddr = Py_BuildValue("(si)", raddr, rport); + if (!py_raddr) + goto error; if (kp->kpcb->ki_type == SOCK_STREAM) { status = kp->kpcb->ki_tstate; } else { @@ -463,12 +477,10 @@ psutil_net_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiiNNii)", fd, AF_INET6, type, py_laddr, py_raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } else if (kp->kpcb->ki_family == AF_UNIX) { struct sockaddr_un *sun_src = (struct sockaddr_un *)&kp->kpcb->ki_src; @@ -480,12 +492,10 @@ psutil_net_connections(PyObject *self, PyObject *args) { py_tuple = Py_BuildValue("(iiissii)", fd, AF_UNIX, type, laddr, raddr, status, pid); - if (!py_tuple) { - printf("Empty tuple\n"); - return 0; - } + if (!py_tuple) + goto error; if (PyList_Append(py_retlist, py_tuple)) - return 0; + goto error; } @@ -496,4 +506,10 @@ psutil_net_connections(PyObject *self, PyObject *args) { kiflist_clear(); kpcblist_clear(); return py_retlist; + +error: + Py_XDECREF(py_tuple); + Py_XDECREF(py_laddr); + Py_XDECREF(py_raddr); + return 0; } From dce014c221bdf610fc353e4f20744f3b94da4b7f Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Thu, 31 Dec 2015 19:48:13 +0100 Subject: [PATCH 24/26] Fix two compilation warnings. Add missing header, fix variable type. --- psutil/arch/bsd/netbsd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/psutil/arch/bsd/netbsd.c b/psutil/arch/bsd/netbsd.c index 80fc7be75..8b38613d3 100644 --- a/psutil/arch/bsd/netbsd.c +++ b/psutil/arch/bsd/netbsd.c @@ -40,6 +40,7 @@ #include "netbsd.h" #include "netbsd_socks.h" +#include "../../_psutil_common.h" #define PSUTIL_KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0) #define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) @@ -339,7 +340,7 @@ char * psutil_get_cmd_args(pid_t pid, size_t *argsize) { int mib[4]; ssize_t st; - int argmax; + size_t argmax; size_t size; char *procargs = NULL; From ed09035baa03166e9261c2644fa36025a959ed51 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Sat, 2 Jan 2016 20:23:54 +0100 Subject: [PATCH 25/26] Check arguments first before using it. --- psutil/_psbsd.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 89f29c76a..3449473e0 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -436,6 +436,10 @@ def threads(self): @wrap_exceptions def connections(self, kind='inet'): + if kind not in conn_tmap: + raise ValueError("invalid %r kind argument; choose between %s" + % (kind, ', '.join([repr(x) for x in conn_tmap]))) + if NETBSD: families, types = conn_tmap[kind] ret = set() @@ -453,9 +457,6 @@ def connections(self, kind='inet'): ret.add(nt) return list(ret) - if kind not in conn_tmap: - raise ValueError("invalid %r kind argument; choose between %s" - % (kind, ', '.join([repr(x) for x in conn_tmap]))) families, types = conn_tmap[kind] rawlist = cext.proc_connections(self.pid, families, types) ret = [] From 343d21b5c24ebc4acaf67b113d9271337fcd3a42 Mon Sep 17 00:00:00 2001 From: Thomas Klausner Date: Sat, 2 Jan 2016 20:38:54 +0100 Subject: [PATCH 26/26] Move check earlier per a comment from giampaolo. --- psutil/arch/bsd/netbsd_socks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psutil/arch/bsd/netbsd_socks.c b/psutil/arch/bsd/netbsd_socks.c index 00070af86..0de191653 100644 --- a/psutil/arch/bsd/netbsd_socks.c +++ b/psutil/arch/bsd/netbsd_socks.c @@ -209,10 +209,10 @@ psutil_proc_connections(PyObject *self, PyObject *args) { PyObject *py_raddr = NULL; pid_t pid; - if (! PyArg_ParseTuple(args, "l", &pid)) + if (py_retlist == NULL) return NULL; - if (py_retlist == NULL) + if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; kiflist_init();