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: Re: [patch] system_process_attributes for OpenBSD Date: Tue, 05 Jan 2021 20:39:25 +0100 Message-ID: <87zh1njhqq.fsf@omarpolo.com> References: <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="5233"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.4.13; emacs 27.1 Cc: Lars Ingebrigtsen , Timo =?utf-8?Q?Myyr=C3=A4?= To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Jan 05 20:40:45 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 1kwsCD-0001EP-2r for ged-emacs-devel@m.gmane-mx.org; Tue, 05 Jan 2021 20:40:45 +0100 Original-Received: from localhost ([::1]:34062 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwsCC-00055S-34 for ged-emacs-devel@m.gmane-mx.org; Tue, 05 Jan 2021 14:40:44 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50742) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwsBB-0004Xe-6w for emacs-devel@gnu.org; Tue, 05 Jan 2021 14:39:41 -0500 Original-Received: from mail.omarpolo.com ([144.91.116.244]:62734) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwsB7-0004vl-TO for emacs-devel@gnu.org; Tue, 05 Jan 2021 14:39:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=omarpolo.com; s=20200327; t=1609875568; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=u+6OjTgGM6hrqgULTudp0X1vZPH5uZ8YWaFmsh2VoyE=; b=YF3C8bs+HQTv8oqsI6tKCeBZ1A9O02mYHc3yjTQj96rxbn/6l2Oz7MXppsxwcT/ZSxNvPg bjYE3978jcZG95EiGN7LWUWtJgKRCSP4JaQRiCfEjZFB6MSOM8Q+xsW7EQqUGzot+HnqTl 9p2pthNvo/uEVt6zdWF1yb6KToyVL00= Original-Received: from localhost (host-80-116-112-105.pool80116.interbusiness.it [80.116.112.105]) by mail.omarpolo.com (OpenSMTPD) with ESMTPSA id aa212e0c (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 5 Jan 2021 20:39:28 +0100 (CET) Original-Received: from venera (localhost [127.0.0.1]) by localhost (OpenSMTPD) with ESMTP id 06ed405d; Tue, 5 Jan 2021 20:39:25 +0100 (CET) In-reply-to: <87k0sw5lzt.fsf@omarpolo.com> 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:262542 Archived-At: Second attempt. Now with 100% less linkages and allocations! Lars: thanks for testing and providing me the form. I sent it and I'm waiting the response. To recap, in the original patch I used kvm(3), because I thought sysctl wasn't an option. Timo pointed out that sysctl actually provides those info; I was only using the wrong mib. The patch below uses sysctl(2) to get processes attributes. There are five stats that I don't know how to collect (cminflt, cmajflt, cstime, ctime and thcount). Everything else seem consistent with top(1). This new patch is equivalent to the first (just a rename from proc->xxx to proc.xxx), with the only exception being how args are concatenated. Before, kvm managed the memory for us, but with sysctl we have to provide the buffer by ourselves. I avoided to dynamically allocate the args string and instead reused the existing storage; this is similar to the freebsd code, but if it seems ugly I can replace that with calloc+strlcat like in the previous patch. Cheers! Omar Polo diff 5ef30fbf11c3ee0ff1c30061dab554b9bd3ce841 /home/op/build/emacs blob - 29c88f5308e47611e425f89a916eca578c86e09f file + src/sysdep.c --- src/sysdep.c +++ src/sysdep.c @@ -53,6 +53,10 @@ along with GNU Emacs. If not, see #endif +#if defined __OpenBSD__ +# include +#endif + #ifdef DARWIN_OS # include #endif @@ -2984,6 +2988,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 @@ -3673,6 +3685,189 @@ system_process_attributes (Lisp_Object pid) return attrs; } +#elif defined __OpenBSD__ + +Lisp_Object +system_process_attributes (Lisp_Object pid) +{ + int proc_id, nentries, fscale, i; + int pagesize = getpagesize (); + int mib[6]; + size_t len; + double pct; + char *ttyname, args[ARG_MAX]; + struct kinfo_proc proc; + struct passwd *pw; + struct group *gr; + struct timespec t; + struct uvmexp uvmexp; + + Lisp_Object attrs = Qnil; + Lisp_Object decoded_comm; + + CHECK_NUMBER (pid); + CONS_TO_INTEGER (pid, int, proc_id); + + len = sizeof proc; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = proc_id; + mib[4] = len; + mib[5] = 1; + if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0) + 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 SIDL: + state[0] = 'I'; + break; + 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); + + len = sizeof (fscale); + mib[0] = CTL_KERN; + mib[1] = KERN_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); + } + + len = sizeof (uvmexp); + mib[0] = CTL_VM; + mib[1] = VM_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); + } + + len = sizeof args; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = proc_id; + mib[3] = KERN_PROC_ARGV; + if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0) + { + char **argv = (char**)args; + + /* concatenate argv reusing the existing storage storage. + sysctl(8) guarantees that "the buffer pointed to by oldp is + filled with an array of char pointers followed by the strings + themselves." */ + for (i = 0; argv[i] != NULL; ++i) + { + if (argv[i+1] != NULL) + { + len = strlen (argv[i]); + argv[i][len] = ' '; + } + } + + AUTO_STRING (comm, *argv); + decoded_comm = code_convert_string_norecord (comm, + Vlocale_coding_system, 0); + attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); + } + + return attrs; +} + #elif defined DARWIN_OS Lisp_Object