From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Omar Polo Newsgroups: gmane.emacs.devel Subject: [patch] system_process_attributes for OpenBSD Date: Fri, 01 Jan 2021 23:29:58 +0100 Message-ID: <87k0sw5lzt.fsf@omarpolo.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33635"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.4.13; emacs 27.1 To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Jan 01 23:31:06 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kvSws-0008cn-AG for ged-emacs-devel@m.gmane-mx.org; Fri, 01 Jan 2021 23:31:06 +0100 Original-Received: from localhost ([::1]:36366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kvSwr-0000lk-7i for ged-emacs-devel@m.gmane-mx.org; Fri, 01 Jan 2021 17:31:05 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kvSw3-0000LD-Vm for emacs-devel@gnu.org; Fri, 01 Jan 2021 17:30:16 -0500 Original-Received: from mail.omarpolo.com ([144.91.116.244]:53277) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kvSvz-0003yl-Ao for emacs-devel@gnu.org; Fri, 01 Jan 2021 17:30:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=omarpolo.com; s=20200327; t=1609540199; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=wIl2mvMG3NFcF+u2kyySJqhJ/jOxnTGUq7GMW/Wbq3U=; b=XCMFzn4xKHccYbcs1dI3FKQjKilORUJTcK5EA2CUZ9dryGzsHq/WmlNVqQ8sQggMWvtWE2 4bSOG+7R10QkdXF/Mt3DSKdZYBwPnFxMmSznXaAfr2ay5R4EYJ+676suZlrfaeXhlWD3KK kh0teZrPPNfV3ucUuHBu5voIpH9mu0s= Original-Received: from localhost (host-80-116-112-105.pool80116.interbusiness.it [80.116.112.105]) by mail.omarpolo.com (OpenSMTPD) with ESMTPSA id 8b309cca (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for ; Fri, 1 Jan 2021 23:29:59 +0100 (CET) Original-Received: from venera (localhost [127.0.0.1]) by localhost (OpenSMTPD) with ESMTP id b2ac9848 for ; Fri, 1 Jan 2021 23:29:58 +0100 (CET) Received-SPF: pass client-ip=144.91.116.244; envelope-from=op@omarpolo.com; helo=mail.omarpolo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:262267 Archived-At: 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 #endif +#if defined __OpenBSD__ +# include +# include +#endif + #ifdef DARWIN_OS # include #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