From: Omar Polo <op@omarpolo.com>
To: emacs-devel@gnu.org
Subject: [patch] system_process_attributes for OpenBSD
Date: Fri, 01 Jan 2021 23:29:58 +0100 [thread overview]
Message-ID: <87k0sw5lzt.fsf@omarpolo.com> (raw)
Hello,
I wanted to try proced, but it doesn't work OOTB on OpenBSD. On emacs
27.1 (installed from packages) list-system-processes returns nil, but on
emacs built from master correctly returns the list of
pids. process-attributes unfortunately returns nil in all the cases.
The attached patch (against the master branch) adds an implementation of
system_process_attributes for OpenBSD. First time hacking on emacs, I
tried to follow the style but please excuse if I forgot something :)
It's not possible to access processes information via sysctl, one has to
use kvm. I studied the sources of top and ps while working on this
patch, and I followed what those programs do. kvm needs to be
initialised with kvm_open [0]: the downside is that a program shouldn't
call two or more time kvm_open (see the BUGS section in the linked
manpage); so I had to use that ugly hack with a static variable: there
is a more elegant way to handle something like this?
There are five stats that I'm not able to collect (cminflt, cmajflt,
cstime, ctime, thcount), but otherwise process-attributes and proced
seem to work just fine:
(process-attributes 66968)
;; =>
((args . "emacs --daemon")
(pmem . 0.9343402932966782)
(pcpu . 2.587890625)
(etime 0 41450 331172 251000)
(rss . 141820)
(vsize . 113460)
(start 24558 64860 215303 0)
(nice . 20)
(pri . 24)
(cutime 0 201 920000 0)
(time 0 376 790000 0)
(stime 0 36 190000 0)
(utime 0 340 600000 0)
(majflt . 5690)
(minflt . 3903171)
(tpgid . -1)
(sess . 66968)
(pgrp . 1000)
(ppid . 1)
(state . "S")
(comm . "emacs-27.1")
(group . "op")
(egid . 1000)
(user . "op")
(euid . 1000))
I'm not sure I got the `state' flag correct, where are they documented?
One last thing, I don't have a copyright assignment and I know very
little about them. I believe I have to sign one if this patch a chance
to be accepted. Can someone please fill me in on the details?
Thanks,
Omar Polo
[0]: http://man.openbsd.org/kvm_open
[1]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/sys/sysctl.h?rev=1.213&content-type=text/plain
diff --git a/configure.ac b/configure.ac
index bf768441fe..6e8d4a54e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1574,6 +1574,8 @@ AC_DEFUN
hpux*) LIBS_SYSTEM="-l:libdld.sl" ;;
+ openbsd) LIBS_SYSTEM="-lkvm" ;;
+
qnxnto) LIBS_SYSTEM="-lsocket" ;;
solaris) LIBS_SYSTEM="-lsocket -lnsl" ;;
diff --git a/src/sysdep.c b/src/sysdep.c
index eeb9d18494..f1e99c0b8d 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -53,6 +53,11 @@
# include <sys/sysctl.h>
#endif
+#if defined __OpenBSD__
+# include <kvm.h>
+# include <sys/proc.h>
+#endif
+
#ifdef DARWIN_OS
# include <libproc.h>
#endif
@@ -2972,6 +2977,14 @@ make_lisp_timeval (struct timeval t)
return make_lisp_time (timeval_to_timespec (t));
}
+#elif defined __OpenBSD__
+
+static Lisp_Object
+make_lisp_timeval (long sec, long usec)
+{
+ return make_lisp_time(make_timespec(sec, usec * 1000));
+}
+
#endif
#ifdef GNU_LINUX
@@ -3661,6 +3674,188 @@ system_process_attributes (Lisp_Object pid)
return attrs;
}
+#elif defined __OpenBSD__
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+ static kvm_t *kd = NULL;
+
+ int proc_id, nentries, fscale, i;
+ int pagesize = getpagesize ();
+ int mib[2];
+ size_t len;
+ double pct;
+ char *ttyname, **argv, *args;
+ struct kinfo_proc *proc;
+ struct passwd *pw;
+ struct group *gr;
+ struct timespec t;
+ struct uvmexp uvmexp;
+
+ Lisp_Object attrs = Qnil;
+ Lisp_Object decoded_comm, decoded_args;
+
+ CHECK_NUMBER (pid);
+ CONS_TO_INTEGER (pid, int, proc_id);
+
+ /* hack */
+ if (kd == NULL)
+ {
+ kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
+ if (kd == NULL)
+ return attrs;
+ }
+
+ proc = kvm_getprocs(kd, KERN_PROC_PID, proc_id, sizeof(*proc), &nentries);
+ if (proc == NULL)
+ return attrs;
+
+ attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc->p_uid)), attrs);
+
+ block_input ();
+ pw = getpwuid (proc->p_uid);
+ unblock_input ();
+ if (pw)
+ attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs);
+
+ attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc->p_svgid)), attrs);
+
+ block_input ();
+ gr = getgrgid (proc->p_svgid);
+ unblock_input ();
+ if (gr)
+ attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
+
+ AUTO_STRING (comm, proc->p_comm);
+ decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
+ attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
+
+ {
+ char state[2] = {'\0', '\0'};
+ switch (proc->p_stat) {
+ case SRUN:
+ state[0] = 'R';
+ break;
+ case SSLEEP:
+ state[0] = 'S';
+ break;
+ case SSTOP:
+ state[0] = 'T';
+ break;
+ case SZOMB:
+ state[0] = 'Z';
+ break;
+ case SDEAD:
+ state[0] = 'D';
+ break;
+ }
+ attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
+ }
+
+ attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc->p_ppid)), attrs);
+ attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc->p_gid)), attrs);
+ attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc->p_sid)), attrs);
+
+ block_input ();
+ ttyname = proc->p_tdev == NODEV ? NULL : devname (proc->p_tdev, S_IFCHR);
+ unblock_input ();
+ if (ttyname)
+ attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
+
+ attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc->p_tpgid)), attrs);
+ attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc->p_uru_minflt)),
+ attrs);
+ attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (proc->p_uru_majflt)),
+ attrs);
+
+ /* FIXME: missing cminflt, cmajflt. */
+
+ attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc->p_uutime_sec,
+ proc->p_uutime_usec)),
+ attrs);
+ attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc->p_ustime_sec,
+ proc->p_ustime_usec)),
+ attrs);
+ t = timespec_add (make_timespec (proc->p_uutime_sec,
+ proc->p_uutime_usec * 1000),
+ make_timespec (proc->p_ustime_sec,
+ proc->p_ustime_usec * 1000));
+ attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
+
+ attrs = Fcons (Fcons (Qcutime, make_lisp_timeval (proc->p_uctime_sec,
+ proc->p_uctime_usec)),
+ attrs);
+
+ /* FIXME: missing cstime and thus ctime. */
+
+ attrs = Fcons (Fcons (Qpri, make_fixnum (proc->p_priority)), attrs);
+ attrs = Fcons (Fcons (Qnice, make_fixnum (proc->p_nice)), attrs);
+
+ /* FIXME: missing thcount (thread count) */
+
+ attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc->p_ustart_sec,
+ proc->p_ustart_usec)),
+ attrs);
+
+ len = (proc->p_vm_tsize + proc->p_vm_dsize + proc->p_vm_ssize) * pagesize >> 10;
+ attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs);
+
+ attrs = Fcons (Fcons (Qrss, make_fixnum (proc->p_vm_rssize * pagesize >> 10)),
+ attrs);
+
+ t = make_timespec (proc->p_ustart_sec,
+ proc->p_ustart_usec * 1000);
+ t = timespec_sub (current_timespec (), t);
+ attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_FSCALE;
+ len = sizeof (fscale);
+ if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1)
+ {
+ pct = (double)proc->p_pctcpu / fscale * 100.0;
+ attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs);
+ }
+
+ mib[0] = CTL_VM;
+ mib[1] = VM_UVMEXP;
+ len = sizeof (uvmexp);
+ if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1)
+ {
+ pct = (100.0 * (double)proc->p_vm_rssize / uvmexp.npages);
+ attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs);
+ }
+
+ /* concatenate process argv */
+
+ if ((argv = kvm_getargv(kd, proc, 0)) == NULL)
+ return attrs;
+
+ len = 0;
+ for (i = 0; argv[i] != NULL; ++i)
+ len += strlen(argv[i]) + 1;
+
+ if ((args = calloc(1, len)) == NULL)
+ return attrs;
+
+ for (i = 0; argv[i] != NULL; ++i)
+ {
+ strlcat(args, argv[i], len);
+ if (argv[i+1] != NULL)
+ strlcat(args, " ", len);
+ }
+
+ AUTO_STRING (args_str, args);
+ decoded_args = code_convert_string_norecord (args_str,
+ Vlocale_coding_system, 0);
+ attrs = Fcons (Fcons (Qargs, decoded_args), attrs);
+
+ free(args);
+
+ return attrs;
+}
+
#elif defined DARWIN_OS
Lisp_Object
next reply other threads:[~2021-01-01 22:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-01 22:29 Omar Polo [this message]
2021-01-02 6:18 ` [patch] system_process_attributes for OpenBSD Lars Ingebrigtsen
2021-01-02 7:29 ` Timo Myyrä
2021-01-02 10:36 ` Omar Polo
2021-01-02 12:16 ` Timo Myyrä
2021-01-02 12:30 ` Omar Polo
2021-01-02 7:43 ` Timo Myyrä
2021-01-05 19:39 ` Omar Polo
2021-01-07 11:23 ` Lars Ingebrigtsen
2021-01-07 11:30 ` Omar Polo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k0sw5lzt.fsf@omarpolo.com \
--to=op@omarpolo.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.