solaris_ps.c

/**
   @file      solaris_ps.c
   @author    Mitch Richling <http://www.mitchr.me/>
   @Copyright Copyright 1999 by Mitch Richling.  All rights reserved.
   @brief     How to access process info in Solairs (like /bin/ps)@EOL
   @Keywords  UNIX Solaris proc procfs ps psinfo
   @Std       ISOC Solaris

              This C program is intended to illustrate how one can
              query process information available through the procfs
              file-system available in Solaris.
   
              /proc contains directories with numeric names
              corresponding to the PIDs of processes currently active
              on the system.  Each directory contains several files
              that have various bits of information about each
              process.  In older versions of Solaris, pre 2.6, the
              content of /proc was simply regular files providing the
              same information through the use of ioctl() calls.  This
              program only works with newer versions of Solaris that
              use directories.  In particular, this program accesses
              the psinfo file contained in each directory.  The UID
              running this program must have access to the
              directories(root for example).  The exit method is not
              very clean and the read call is also not very clean...

   @Tested    
              - Solaris 2.7
              - Solaris 2.8
              - Solaris 2.9
              - BROKEN: Linux   -- incompatable /proc
              - BROKEN: MacOS X -- no /proc
              - BROKEN: Solaris 2.5.x
*/

#include <dirent.h>             /* UNIX dirs       POSIX */
#include <errno.h>              /* error stf       POSIX */
#include <fcntl.h>              /* UNIX file ctrl  UNIX  */
#include <procfs.h>             /* Solaris proc    SUN   */
#include <stdio.h>              /* I/O lib         ISOC  */
#include <stdlib.h>             /* Standard Lib    ISOC  */
#include <string.h>             /* Strings         ISOC  */
#include <sys/stat.h>           /* UNIX stat       POSIX */
#include <sys/types.h>          /* UNIX types      POSIX */

int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
  int fd;
  char dat[512];
  struct psinfo *thePsInfo;
  char dirToRead[] = "/proc";
  DIR *dp;
  struct dirent *dep;
  int errorCount, haveMore;
  char fileToOpen[1024];

  dp = opendir(dirToRead);
  if(dp == NULL) {
    printf("ERROR: Could not open directory(%s).\n", dirToRead);
    exit(10);
  } /* end if */

  errorCount = 0;
  haveMore = 1;
  do {
    errno = 0;
    dep = readdir(dp);
    if(dep == NULL) {
      if(errno) {
        errorCount++;
        perror(NULL);
      } else
        haveMore = 0;
    } else {
      sprintf(fileToOpen, "/proc/%s/psinfo", dep->d_name);

      fd = open(fileToOpen, O_RDONLY);
      if(fd >= 0) {
        read(fd, dat, 416);
        thePsInfo = (struct psinfo *)dat;
        printf("PID: %-10s  CMD: %s \n", dep->d_name, thePsInfo->pr_fname);
        close(fd);
      } /* end if */
    } /* end if/else */
  } while((errorCount < 10000) && (haveMore));

  if(haveMore) {
    printf("Exit due to repeated errors.\n");
  } /* end if */

  if(closedir(dp) < 0) {
    printf("ERROR: Could not close directory(%s).\n", dirToRead);
    exit(10);
  } /* end if */

  exit(0);
} /* end func main */

Generated by GNU Enscript 1.6.5.2.