$NetBSD: patch-ah,v 1.11 2008/01/04 21:05:57 markd Exp $

--- kicker/applets/naughty/NaughtyProcessMonitor.cpp.orig	2005-10-11 04:03:59.000000000 +1300
+++ kicker/applets/naughty/NaughtyProcessMonitor.cpp
@@ -20,8 +20,9 @@
 
 /* OpenBSD support by Jean-Yves Burlett <jean-yves@burlett.org> */
 
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__NetBSD__)
 #include <sys/param.h>
+#include <sys/time.h>
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 #include <sys/ucred.h>
@@ -29,6 +30,11 @@
 #include <stdlib.h>
 #endif
 
+#ifdef __NetBSD__
+#include <kvm.h>
+#include <sys/sched.h>
+#endif
+
 #include <sys/types.h>
 #include <signal.h>
 #include <unistd.h>
@@ -67,10 +73,13 @@ class NaughtyProcessMonitorPrivate
     QTimer * timer_;
     QMap<ulong, uint> loadMap_;
     QMap<ulong, uint> scoreMap_;
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__NetBSD__)
     QMap<ulong, uint> cacheLoadMap_;
     QMap<ulong, uid_t> uidMap_;
 #endif
+#ifdef __NetBSD__
+    kvm_t *kd;
+#endif
     uint oldLoad_;
     uint triggerLevel_;
 
@@ -95,11 +104,17 @@ NaughtyProcessMonitor::NaughtyProcessMon
   d->interval_ = interval * 1000;
   d->triggerLevel_ = triggerLevel;
   d->timer_ = new QTimer(this);
+#ifdef __NetBSD__
+  d->kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
+#endif
   connect(d->timer_, SIGNAL(timeout()), this, SLOT(slotTimeout()));
 }
 
 NaughtyProcessMonitor::~NaughtyProcessMonitor()
 {
+#ifdef __NetBSD__
+  kvm_close(d->kd);
+#endif
   delete d;
 }
 
@@ -219,7 +234,7 @@ NaughtyProcessMonitor::canKill(ulong pid
 //  uint d(l[4].toUInt());
 
   return geteuid() == a;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
   // simply check if entry exists in the uid map and use it
   if (!d->uidMap_.contains(pid))
       return false ;
@@ -234,7 +249,7 @@ NaughtyProcessMonitor::canKill(ulong pid
   QString
 NaughtyProcessMonitor::processName(ulong pid) const
 {
-#if defined(__linux__) || defined(__OpenBSD__)
+#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
 #ifdef __linux__
   QFile f("/proc/" + QString::number(pid) + "/cmdline");
 
@@ -283,6 +298,29 @@ NaughtyProcessMonitor::processName(ulong
   QString unicode(QString::fromLocal8Bit(argv[0]));
 
   free (argv) ;
+#elif defined(__NetBSD__)
+  struct kinfo_proc2 *p;
+  int len;
+  char **argv;
+
+  p = kvm_getproc2(d->kd, KERN_PROC_PID, pid,
+		   sizeof(struct kinfo_proc2), &len);
+  if (len < 1) {
+    return i18n("Unknown") ;
+  }
+  
+ // Now strip 'kdeinit:' prefix.
+  QString unicode(QString::fromLocal8Bit(p->p_comm));
+
+  if (unicode == "kdeinit") {
+      argv = kvm_getargv2(d->kd, p, 100);
+      while (argv != NULL && (*argv == "kdeinit:")) {
+	  argv++;
+      }
+      if (argv != NULL) {
+	  unicode = *argv;
+      }
+  }
 #endif
 
   QStringList parts(QStringList::split(' ', unicode));
@@ -350,6 +388,28 @@ NaughtyProcessMonitor::cpuLoad() const
   d->oldLoad_ = load ;
   
   return (forgetThisOne ? 0 : diff);
+#elif defined(__NetBSD__)
+  int mib[2] ;
+  u_int64_t cp_time[CPUSTATES] ;
+  size_t size ;
+  uint load, diff ;
+  bool forgetThisOne = 0 == d->oldLoad_;
+
+  // fetch CPU time statistics
+
+  mib[0] = CTL_KERN ;
+  mib[1] = KERN_CP_TIME ;
+
+  size = CPUSTATES * sizeof(cp_time[0]) ;
+  
+  if (-1 == sysctl (mib, 2, cp_time, &size, NULL, 0))
+      return 0 ;
+  
+  load = cp_time[CP_USER] + cp_time[CP_SYS] ;
+  diff = load - d->oldLoad_ ;
+  d->oldLoad_ = load ;
+  
+  return (forgetThisOne ? 0 : diff);
 #else
   return 0;
 #endif
@@ -420,6 +480,30 @@ NaughtyProcessMonitor::pidList() const
   free (kp) ;
   
   return l ;
+#elif defined(__NetBSD__)
+  struct kinfo_proc2 *kp;
+  int nentries ;
+  int i ;
+  QValueList<ulong> l;
+
+  kp = kvm_getproc2(d->kd, KERN_PROC_ALL, 0,
+		   sizeof(struct kinfo_proc2), &nentries);
+
+  // time statistics and euid data are fetched only for processes in
+  // the pidList, so, instead of doing one sysctl per process for
+  // getLoad and canKill calls, simply cache the data we already have.
+
+  d->cacheLoadMap_.clear () ;
+  d->uidMap_.clear () ;
+  for (i = 0; i < nentries; i++) {
+      l << (unsigned long) kp[i].p_pid ;
+      d->cacheLoadMap_.insert (kp[i].p_pid,
+			       kp[i].p_cpticks) ;
+      d->uidMap_.insert (kp[i].p_pid,
+			 kp[i].p_uid) ;
+  }
+
+  return l ;
 #else
   QValueList<ulong> l;
   return l;
@@ -447,7 +531,7 @@ NaughtyProcessMonitor::getLoad(ulong pid
   load = userTime + sysTime;
 
   return true;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
   // use cache
   if (!d->cacheLoadMap_.contains(pid))
       return false ;
@@ -464,7 +548,7 @@ NaughtyProcessMonitor::getLoad(ulong pid
   bool
 NaughtyProcessMonitor::kill(ulong pid) const
 {
-#if defined(__linux__) || defined(__OpenBSD__)
+#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
   return 0 == ::kill(pid, SIGKILL);
 #else
   Q_UNUSED( pid );
