ip1981

pidof for illumos

Dec 22nd, 2012
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.13 KB | None | 0 0
  1. #ifndef _XOPEN_SOURCE
  2. # define _XOPEN_SOURCE 500
  3. #endif
  4.  
  5. /* C headers */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <errno.h>
  10.  
  11. /* System headers */
  12. #include <sys/types.h>
  13. #include <dirent.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16.  
  17. /* illumos headers */
  18. #include <procfs.h>
  19.  
  20. static int single_shot = 0;
  21. static int only_same_root = 0;
  22. static int scripts_too = 0;
  23. static int *omit_pids = NULL;
  24. static int progidx = 0;
  25.  
  26. static const char *progname;
  27.  
  28. void usage()
  29. {
  30.     printf("Usage: %s [OPTIONS] program [program ...]\n", progname);
  31.     printf("Find the process ID of a running program.\n\n");
  32.  
  33.     printf("Options:\n");
  34.     printf("  -s      single shot - only return one pid.\n");
  35.     printf("  -c      only return process ids that are running with the same root directory.\n");
  36.     printf("  -x      scripts too - also return process ids of shells running the named scripts.\n");
  37.     printf("  -o pid  omit processes with that process id (-o pid1,pid2 or -o pid1 -o pid2, etc.)\n");
  38.     printf("\n");
  39.     printf("  -h      this help message.\n");
  40.     printf("\n");
  41.  
  42.     printf("Exit status:\n");
  43.     printf("  0      at least one program was found with the requested name.\n");
  44.     printf("  1      no program was found with the requested name.\n");
  45.  
  46.     exit(1);
  47. }
  48.  
  49.  
  50. void parse_args(int argc, char *argv[])
  51. {
  52.     int opt;
  53.  
  54.     progname = argv[0];
  55.  
  56.     while ((opt = getopt(argc, argv, "hscxo:")) != -1) {
  57.        switch (opt) {
  58.        case 's':
  59.            single_shot++;
  60.            break;
  61.        case 'c':
  62.            only_same_root++;
  63.            break;
  64.        case 'x':
  65.            scripts_too++;
  66.            break;
  67.        default:
  68.            usage();
  69.        }
  70.     }
  71.  
  72.     /* all arguments after options are program names */
  73.     progidx = optind;
  74. }
  75.  
  76. int name_matches(const char *name, int start, int n, char *progs[])
  77. {
  78.     while (start < n) {
  79.         if (progs[start][0] != '\0') {
  80.             if (0 == strcmp(name, progs[start])) {
  81.                 if (single_shot) progs[start] = "";
  82.                 return 1;
  83.             }
  84.         }
  85.         start++;
  86.     }
  87.     return 0;
  88. }
  89.  
  90.  
  91. int main(int argc, char *argv[])
  92. {
  93.     DIR *dirp;            /* directory handler for /proc */
  94.     struct dirent *pdr    /* dir entry for /proc/<pid> */;
  95.     psinfo_t pi;          /* contents of /proc/<pid>/psinfo */
  96.     int fd;               /* file descriptor for /proc/<pid>/psinfo */
  97.     int rc;               /* return value of various function*/
  98.     const char *pid_s;    /* string representation of pid */
  99.     int found = 0;        /* number of found pids */
  100.  
  101. #define MAX_PID_LENGTH 6  /* 999999 max, see http://docs.oracle.com/cd/E19082-01/819-2724/chapter2-107/index.html */
  102.     char fname[6 + MAX_PID_LENGTH + 7 + 1]; /* length of /proc/<pid>/psinfo + '0' */
  103.  
  104.     parse_args(argc, argv);
  105.  
  106.     if (!(dirp = opendir("/proc"))) {
  107.         perror("Failed to open directory /proc");
  108.         exit(1);
  109.     }
  110.  
  111.     while ((pdr = readdir(dirp))) {
  112.         if (pdr->d_name[0] == '.') /* skip . and .. */
  113.             continue;
  114.  
  115.         pid_s = pdr->d_name;
  116.         rc = snprintf(fname, sizeof(fname), "/proc/%s/psinfo", pid_s);
  117.         if (rc < 0) {
  118.             perror("snprintf failed");
  119.             errno = 0;
  120.             continue;
  121.         }
  122.         if (rc >= (int) sizeof(fname)) {
  123.             fprintf(stderr, "Not enough space to hold `%s'\n", pid_s);
  124.             continue;
  125.         }
  126.         if ((fd = open(fname, O_RDONLY)) < 0) {
  127.             perror(fname);
  128.             errno = 0;
  129.             continue;
  130.         }
  131.  
  132.         if (read(fd, (void *)&pi, sizeof(pi)) < 0) {
  133.             perror(fname);
  134.             errno = 0;
  135.         } else {
  136.             if (name_matches(pi.pr_fname, progidx, argc, argv)) {
  137.                 printf("%s ", pid_s);
  138.                 found++;
  139.             }
  140.             /*
  141.             printf("%s\n", pi.pr_fname);
  142.             printf("%s\n", pi.pr_psargs);
  143.             */
  144.         }
  145.  
  146.         (void) close(fd);
  147.     }
  148.  
  149.     if (errno) {
  150.         perror("Error while listing /proc");
  151.     }
  152.    
  153.     (void) closedir(dirp);
  154.     return (found > 0) ? 0 : 1;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment