home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / misc-utils / procs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  2.5 KB  |  114 lines

  1. /*
  2.  *  procs.c -- functions to parse the linux /proc filesystem.
  3.  *  (c) 1994 salvatore valente <svalente@mit.edu>
  4.  *
  5.  *   this program is free software.  you can redistribute it and
  6.  *   modify it under the terms of the gnu general public license.
  7.  *   there is no warranty.
  8.  *
  9.  *   faith
  10.  *   1.2
  11.  *   1995/02/23 01:20:40
  12.  *
  13.  */
  14.  
  15. #define _POSIX_SOURCE 1
  16.  
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <dirent.h>
  23. #include <ctype.h>
  24. #include <unistd.h>
  25.  
  26. extern char *mybasename (char *);
  27. static char *parse_parens (char *buf);
  28.  
  29. int *get_pids (char *process_name, int get_all)
  30. {
  31.     DIR *dir;
  32.     struct dirent *ent;
  33.     int status;
  34.     char *dname, fname[100], *cp, buf[256];
  35.     struct stat st;
  36.     uid_t uid;
  37.     FILE *fp;
  38.     int pid, *pids, num_pids, pids_size;
  39.  
  40.     dir = opendir ("/proc");
  41.     if (! dir) {
  42.     perror ("opendir /proc");
  43.     return NULL;
  44.     }
  45.     uid = getuid ();
  46.     pids = NULL;
  47.     num_pids = pids_size = 0;
  48.  
  49.     while ((ent = readdir (dir)) != NULL) {
  50.     dname = ent->d_name;
  51.     if (! isdigit (*dname)) continue;
  52.     pid = atoi (dname);
  53.     sprintf (fname, "/proc/%d/cmdline", pid);
  54.     /* get the process owner */
  55.     status = stat (fname, &st);
  56.     if (status != 0) continue;
  57.     if (! get_all && uid != st.st_uid) continue;
  58.     /* get the command line */
  59.     fp = fopen (fname, "r");
  60.     if (! fp) continue;
  61.     cp = fgets (buf, sizeof (buf), fp);
  62.     fclose (fp);
  63.     /* an empty command line means the process is swapped out */
  64.     if (! cp || ! *cp) {
  65.         /* get the process name from the statfile */
  66.         sprintf (fname, "/proc/%d/stat", pid);
  67.         fp = fopen (fname, "r");
  68.         if (! fp) continue;
  69.         cp = fgets (buf, sizeof (buf), fp);
  70.         if (cp == NULL) continue;
  71.         fclose (fp);
  72.         cp = parse_parens (buf);
  73.         if (cp == NULL) continue;
  74.     }
  75.     /* ok, we got the process name. */
  76.     if (strcmp (process_name, mybasename (cp))) continue;
  77.     while (pids_size < num_pids + 2) {
  78.         pids_size += 5;
  79.         pids = (int *) realloc (pids, sizeof (int) * pids_size);
  80.     }
  81.     pids[num_pids++] = pid;
  82.     pids[num_pids] = -1;
  83.     }
  84.     closedir (dir);
  85.     return (pids);
  86. }
  87.  
  88. /*
  89.  *  parse_parens () -- return an index just past the first open paren in
  90.  *    buf, and terminate the string at the matching close paren.
  91.  */
  92. static char *parse_parens (char *buf)
  93. {
  94.     char *cp, *ip;
  95.     int depth;
  96.  
  97.     cp = strchr (buf, '(');
  98.     if (cp == NULL) return NULL;
  99.     cp++;
  100.     depth = 1;
  101.     for (ip = cp; *ip; ip++) {
  102.     if (*ip == '(')
  103.         depth++;
  104.     if (*ip == ')') {
  105.         depth--;
  106.         if (depth == 0) {
  107.         *ip = 0;
  108.         break;
  109.         }
  110.     }
  111.     }
  112.     return cp;
  113. }
  114.