summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2020-03-21 23:41:23 +0100
committerLeah Neukirchen <leah@vuxu.org>2020-03-21 23:41:23 +0100
commit381a0917c48ce419ececd3ed560bf42fb8422d07 (patch)
tree3cf76569d4366883cff3656a8deb2438d1c27305
downloadpx-381a0917c48ce419ececd3ed560bf42fb8422d07.tar.gz
px-381a0917c48ce419ececd3ed560bf42fb8422d07.tar.xz
px-381a0917c48ce419ececd3ed560bf42fb8422d07.zip
initial commit of px
-rw-r--r--Makefile24
-rw-r--r--px.c168
-rw-r--r--px.sh7
3 files changed, 199 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..59bd863
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+ALL=px
+
+CFLAGS=-g -O2 -Wall -Wno-switch -Wextra -Wwrite-strings
+LDFLAGS=-lprocps
+
+DESTDIR=
+PREFIX=/usr/local
+BINDIR=$(PREFIX)/bin
+MANDIR=$(PREFIX)/share/man
+
+all: $(ALL)
+
+clean: FRC
+ rm -f $(ALL)
+
+install: FRC all
+ mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1
+ install -m0755 $(ALL) $(DESTDIR)$(BINDIR)
+ install -m0644 $(ALL:=.1) $(DESTDIR)$(MANDIR)/man1
+
+README: px.1
+ mandoc -Tutf8 $< | col -bx >$@
+
+FRC:
diff --git a/px.c b/px.c
new file mode 100644
index 0000000..7547c00
--- /dev/null
+++ b/px.c
@@ -0,0 +1,168 @@
+// gcc -g -O2 -Wall -o px px.c -lprocps
+
+#include <sys/sysinfo.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <proc/readproc.h>
+
+time_t seconds_since_boot;
+int Hertz;
+
+static int want_this_proc_pcpu(proc_t *buf){
+ unsigned long long used_jiffies;
+ unsigned long pcpu = 0;
+ unsigned long long seconds;
+
+// if(!want_this_proc(buf)) return 0;
+
+ used_jiffies = buf->utime + buf->stime;
+// if(include_dead_children) used_jiffies += (buf->cutime + buf->cstime);
+
+ seconds = seconds_since_boot - buf->start_time / Hertz;
+ if(seconds) pcpu = (used_jiffies * 1000ULL / Hertz) / seconds;
+
+ buf->pcpu = pcpu; // fits in an int, summing children on 128 CPUs
+
+ return 1;
+}
+
+static void
+print_human(intmax_t i)
+{
+ double d = i;
+ const char *u = "\0\0K\0M\0G\0T\0P\0E\0Z\0Y\0";
+ while (d >= 1024) {
+ u += 2;
+ d /= 1024.0;
+ }
+
+ if (!*u)
+ printf("%5.0f", d);
+ else if (d < 10.0)
+ printf("%4.1f%s", d, u);
+ else
+ printf("%4.0f%s", d, u);
+}
+
+int
+main(int argc, char *argv[])
+{
+ proc_t **result;
+ int hz;
+
+ if((hz = sysconf(_SC_CLK_TCK)) > 0){
+ Hertz = hz;
+ } else {
+ Hertz = 100; /* shrug */
+ }
+
+ struct sysinfo si;
+ sysinfo(&si);
+
+ seconds_since_boot = si.uptime;
+ time_t now = time(0);
+
+ result = readproctab(PROC_FILLMEM | PROC_FILLCOM | PROC_FILLUSR |
+ PROC_FILLSTAT | PROC_FILLSTATUS);
+
+ int matched = 0;
+
+ for (; *result; result++) {
+ proc_t *p = *result;
+
+ if (argc > 0) {
+ for (int i = 1; i < argc; i++)
+ if (strstr(p->cmd, argv[i]))
+ goto match;
+ continue;
+match:
+ matched++;
+ } else {
+ matched++;
+ }
+
+ if (matched == 1)
+ printf(" PID USER %%CPU VSZ RSS START ELAPSED TIME COMMAND\n");
+
+ want_this_proc_pcpu(p);
+
+ printf("%5d", p->tid);
+ printf(" %-8.8s", p->euser);
+ printf(" %4.1f", p->pcpu/10.0);
+ print_human(p->vm_size*1024);
+ print_human(p->vm_rss*1024);
+
+ time_t start;
+ time_t seconds_ago;
+ start = (now - si.uptime) + p->start_time / Hertz;
+ seconds_ago = now - start;
+ if(seconds_ago < 0) seconds_ago=0;
+
+ char buf[7];
+ if (seconds_ago > 3600*24)
+ strftime(buf, sizeof buf, "%b%d", localtime(&start));
+ else
+ strftime(buf, sizeof buf, "%H:%M", localtime(&start));
+ printf(" %s", buf);
+
+ time_t t = seconds_ago;
+ unsigned dd,hh,mm,ss;
+ ss = t%60;
+ t /= 60;
+ mm = t%60;
+ t /= 60;
+ hh = t%24;
+ t /= 24;
+ dd = t;
+
+ if (dd)
+ printf(" %3ud%02uh", dd, hh);
+ else if (hh)
+ printf(" %2uh%02um", hh, mm);
+ else
+ printf(" %2u:%02u", mm, ss);
+
+
+ t = (p->utime + p->stime) / Hertz;
+ ss = t%60;
+ t /= 60;
+ mm = t%60;
+ t /= 60;
+ hh = t%24;
+
+ if (hh)
+ printf(" %3uh%02u", hh, mm);
+ else
+ printf(" %2u:%02u", mm, ss);
+
+ if (p->cmdline) {
+ for (int i = 0; p->cmdline[i]; i++) {
+ printf(" %s", p->cmdline[i]);
+ }
+ } else {
+ // kernel threads
+ printf(" [%s]", p->cmd);
+ }
+
+ if (p->state == 'Z')
+ printf(" <defunct>");
+ printf("\n");
+
+#if 0
+ printf("%d %s %f %ld %ld %ld %lld %lld %lld %s\n",
+ p->tid, p->euser, p->pcpu/10.0, pmem,
+ p->vm_size, p->vm_rss, p->start_time, 0ULL, p->utime,
+ p->cmd
+ );
+#endif
+ }
+
+// freeproctab(result);
+
+ exit(matched > 0);
+}
diff --git a/px.sh b/px.sh
new file mode 100644
index 0000000..f389a0b
--- /dev/null
+++ b/px.sh
@@ -0,0 +1,7 @@
+px() {
+ ps wwp ${$(pgrep -d, "${(j:|:)@}"):?no matches} \
+ -o pid,user:6,%cpu,%mem,vsz:10,rss:10,bsdstart,etime:12,bsdtime,args |
+ sed '1s/ \(VSZ\|RSS\)/\1/g' |
+ numfmt --header --field 5,6 --from-unit=1024 --to=iec --format "%5f"
+}
+