changeset 100567:387ca5b2d869

* sysdep.c (system_process_attributes): Add implementation for Solaris. * s/sol2-10.h (HAVE_PROCFS, _STRUCTURED_PROC): New defines.
author Dan Nicolaescu <dann@ics.uci.edu>
date Fri, 19 Dec 2008 20:58:37 +0000
parents 91f7b663a0fd
children 3520539e2319
files src/ChangeLog src/s/sol2-10.h src/sysdep.c
diffstat 3 files changed, 150 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Dec 19 20:52:15 2008 +0000
+++ b/src/ChangeLog	Fri Dec 19 20:58:37 2008 +0000
@@ -1,6 +1,9 @@
 2008-12-19  Dan Nicolaescu  <dann@ics.uci.edu>
 
 	* sysdep.c: Include alloca.h.
+	(system_process_attributes): Add implementation for Solaris.
+
+	* s/sol2-10.h (HAVE_PROCFS, _STRUCTURED_PROC): New defines.
 
 2008-12-19  Dan Nicolaescu  <dann@ics.uci.edu>
 
--- a/src/s/sol2-10.h	Fri Dec 19 20:52:15 2008 +0000
+++ b/src/s/sol2-10.h	Fri Dec 19 20:58:37 2008 +0000
@@ -21,5 +21,11 @@
 #undef UNEXEC
 #define UNEXEC unexsol.o
 
+/* This is used in list_system_processes.  */
+#define HAVE_PROCFS 1
+
+/* This is needed for the system_process_attributes implementation.  */
+#define _STRUCTURED_PROC 1
+
 /* arch-tag: 7c51a134-5469-4d16-aa00-d69224640eeb
    (do not change this comment) */
--- a/src/sysdep.c	Fri Dec 19 20:52:15 2008 +0000
+++ b/src/sysdep.c	Fri Dec 19 20:58:37 2008 +0000
@@ -3289,7 +3289,7 @@
 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
 
 static Lisp_Object
-procfs_ttyname (rdev)
+procfs_ttyname (int rdev)
 {
   FILE *fdev = NULL;
   char name[PATH_MAX];
@@ -3360,8 +3360,7 @@
 }
 
 Lisp_Object
-system_process_attributes (pid)
-     Lisp_Object pid;
+system_process_attributes (Lisp_Object pid)
 {
   char procfn[PATH_MAX], fn[PATH_MAX];
   struct stat st;
@@ -3608,6 +3607,145 @@
   UNGCPRO;
   return attrs;
 }
+#elif defined (SOLARIS2) && defined (HAVE_PROCFS)
+
+/* The <procfs.h> header does not like to be included if _LP64 is defined and
+   __FILE_OFFSET_BITS == 64.  This is an ugly workaround that.  */
+#if !defined (_LP64) && defined (_FILE_OFFSET_BITS) &&  (_FILE_OFFSET_BITS  ==  64)
+#define PROCFS_FILE_OFFSET_BITS_HACK 1
+#undef _FILE_OFFSET_BITS
+#else
+#define PROCFS_FILE_OFFSET_BITS_HACK 0
+#endif
+
+#include <procfs.h>
+
+#if PROCFS_FILE_OFFSET_BITS_HACK ==  1
+#define _FILE_OFFSET_BITS 64
+#endif /* PROCFS_FILE_OFFSET_BITS_HACK ==  1 */
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+  char procfn[PATH_MAX], fn[PATH_MAX];
+  struct stat st;
+  struct passwd *pw;
+  struct group *gr;
+  char *procfn_end;
+  struct psinfo pinfo;
+  int fd;
+  ssize_t nread;
+  int proc_id, uid, gid;
+  Lisp_Object attrs = Qnil;
+  Lisp_Object decoded_cmd, tem;
+  struct gcpro gcpro1, gcpro2;
+  EMACS_INT uid_eint, gid_eint;
+
+  CHECK_NUMBER_OR_FLOAT (pid);
+  proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
+  sprintf (procfn, "/proc/%u", proc_id);
+  if (stat (procfn, &st) < 0)
+    return attrs;
+
+  GCPRO2 (attrs, decoded_cmd);
+
+  /* euid egid */
+  uid = st.st_uid;
+  /* Use of EMACS_INT stops GCC whining about limited range of data type.  */
+  uid_eint = uid;
+  attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
+  BLOCK_INPUT;
+  pw = getpwuid (uid);
+  UNBLOCK_INPUT;
+  if (pw)
+    attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
+
+  gid = st.st_gid;
+  gid_eint = gid;
+  attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
+  BLOCK_INPUT;
+  gr = getgrgid (gid);
+  UNBLOCK_INPUT;
+  if (gr)
+    attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
+
+  strcpy (fn, procfn);
+  procfn_end = fn + strlen (fn);
+  strcpy (procfn_end, "/psinfo");
+  fd = emacs_open (fn, O_RDONLY, 0);
+  if (fd >= 0
+      && (nread = read (fd, (char*)&pinfo, sizeof(struct psinfo)) > 0))
+    {
+          attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
+	  attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
+	  attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
+
+	  {
+	    char state_str[2];
+	    state_str[0] =  pinfo.pr_lwp.pr_sname;
+	    state_str[1] =  '\0';
+	    tem =   build_string (state_str);
+	    attrs =  Fcons (Fcons (Qstate,  tem),  attrs);
+	  }
+
+	  /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
+	     need to get a string from it. */
+
+	  /* FIXME: missing: Qtpgid */
+
+	  /* FIXME: missing:
+		Qminflt
+		Qmajflt
+		Qcminflt
+		Qcmajflt
+
+		Qstime
+		Qcstime
+		Are they available? */
+
+	  attrs = Fcons (Fcons (Qutime,
+	  			list3 (make_number (pinfo.pr_time.tv_sec >> 16),
+	  			       make_number (pinfo.pr_time.tv_sec & 0xffff),
+	  			       make_number (pinfo.pr_time.tv_nsec))),
+	  		 attrs);
+
+	  attrs = Fcons (Fcons (Qcutime,
+	  			list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
+	  			       make_number (pinfo.pr_ctime.tv_sec & 0xffff),
+	  			       make_number (pinfo.pr_ctime.tv_nsec))),
+	  		 attrs);
+
+	  attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
+	  attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
+	  attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
+
+	  attrs = Fcons (Fcons (Qstart,
+	  			list3 (make_number (pinfo.pr_start.tv_sec >> 16),
+	  			       make_number (pinfo.pr_start.tv_sec & 0xffff),
+	  			       make_number (pinfo.pr_start.tv_nsec))),
+	  		 attrs);
+	  attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
+	  attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
+
+	  /* pr_pctcpu and pr_pctmem are encoded as a fixed point 16 bit number in  [0 ... 1].  */
+	  attrs = Fcons (Fcons (Qpcpu, (pinfo.pr_pctcpu * 100.0) / (double)0x8000), attrs);
+	  attrs = Fcons (Fcons (Qpmem, (pinfo.pr_pctmem * 100.0) / (double)0x8000), attrs);
+
+	  decoded_cmd
+	    =  code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
+								  strlen (pinfo.pr_fname)),
+					     Vlocale_coding_system,  0);
+	  attrs =  Fcons (Fcons (Qcomm,  decoded_cmd),  attrs);
+	  decoded_cmd
+	    =  code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
+								  strlen (pinfo.pr_psargs)),
+					     Vlocale_coding_system,  0);
+	  attrs =  Fcons (Fcons (Qargs,  decoded_cmd),  attrs);
+    }
+
+  UNGCPRO;
+  return attrs;
+}
 
 #elif !defined (WINDOWSNT)