emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

implement Solaris support for system-process-attributes and list-system-


From: Dan Nicolaescu
Subject: implement Solaris support for system-process-attributes and list-system-processes
Date: Thu, 18 Dec 2008 01:16:19 -0800 (PST)

These functions are needed so that M-x proced can work.  They need
system specific implementation.  At the moment they are only supported
on GNU/Linux and Windows.

There are a few warts in getting these 2 functions supported on Solaris,
and I would like some feedback.

1. First some include hackery:

#ifdef SOLARIS2
#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
#endif /* SOLARIS2 */

procfs.h is the header file that contains the proc data structures, but
it has an #error if compiled in 32 bit mode and _FILE_OFFSET_BITS is
64.
emacs/src/config.in will define _FILE_OFFSET_BITS to 64 when compiled on
a 32 bit solaris system.  Hence the above hackery.


2. process.c has a function `procfs_list_system_processes' that works on
Solaris (and probably on all systems that use a /proc).  
The problem is that procfs_list_system_processes is inside a #ifdef HAVE_PROCFS
that contains a few other functions (time_from_jiffies, get_up_time)
that are Linux specific.
Should I move those functions inside a #ifdef LINUX ?

3. An implementation for the Solaris version of
system-process-attributes is at the end of this message.

4. Flist_system_processes and Fsystem_process_attributes use the
LISTPROC and PROCATTR macros for function calls that need to be defined in 
src/s/*.h 
These macros are different from how other platform specific functions
are implemented in emacs, and they seem to be a bit redundant: the
functions to implement these are system specific anyway....

So what's the best way to integrate Solaris support?
Again the existing procfs_list_system_processes function can probably be
used by all systems using /proc, but procfs_system_process_attributes
is very likely to be OS specific. 

Thanks


static Lisp_Object
procfs_system_process_attributes (pid)
     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/%lu", 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;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]