Upload Tizen:Base source
[framework/base/util-linux-ng.git] / misc-utils / procs.c
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 #include "kill.h"
26
27 extern char *mybasename (char *);
28 static char *parse_parens (char *buf);
29
30 int *
31 get_pids (char *process_name, int get_all) {
32     DIR *dir;
33     struct dirent *ent;
34     int status;
35     char *dname, fname[100], *cp, buf[256];
36     struct stat st;
37     uid_t uid;
38     FILE *fp;
39     int pid, *pids, num_pids, pids_size;
40
41     dir = opendir ("/proc");
42     if (! dir) {
43         perror ("opendir /proc");
44         return NULL;
45     }
46     uid = getuid ();
47     pids = NULL;
48     num_pids = pids_size = 0;
49
50     while ((ent = readdir (dir)) != NULL) {
51         dname = ent->d_name;
52         if (! isdigit (*dname)) continue;
53         pid = atoi (dname);
54         sprintf (fname, "/proc/%d/cmdline", pid);
55         /* get the process owner */
56         status = stat (fname, &st);
57         if (status != 0) continue;
58         if (! get_all && uid != st.st_uid) continue;
59         /* get the command line */
60         fp = fopen (fname, "r");
61         if (! fp) continue;
62         cp = fgets (buf, sizeof (buf), fp);
63         fclose (fp);
64         /* an empty command line means the process is swapped out */
65         if (! cp || ! *cp) {
66             /* get the process name from the statfile */
67             sprintf (fname, "/proc/%d/stat", pid);
68             fp = fopen (fname, "r");
69             if (! fp) continue;
70             cp = fgets (buf, sizeof (buf), fp);
71             if (cp == NULL) continue;
72             fclose (fp);
73             cp = parse_parens (buf);
74             if (cp == NULL) continue;
75         }
76         /* ok, we got the process name. */
77         if (strcmp (process_name, mybasename (cp))) continue;
78         while (pids_size < num_pids + 2) {
79             pids_size += 5;
80             pids = (int *) realloc (pids, sizeof (int) * pids_size);
81         }
82         pids[num_pids++] = pid;
83         pids[num_pids] = -1;
84     }
85     closedir (dir);
86     return (pids);
87 }
88
89 /*
90  *  parse_parens () -- return an index just past the first open paren in
91  *      buf, and terminate the string at the matching close paren.
92  */
93 static char *parse_parens (char *buf)
94 {
95     char *cp, *ip;
96     int depth;
97
98     cp = strchr (buf, '(');
99     if (cp == NULL) return NULL;
100     cp++;
101     depth = 1;
102     for (ip = cp; *ip; ip++) {
103         if (*ip == '(')
104             depth++;
105         if (*ip == ')') {
106             depth--;
107             if (depth == 0) {
108                 *ip = 0;
109                 break;
110             }
111         }
112     }
113     return cp;
114 }
115
116 char *mybasename (char *path)
117 {
118     char *cp;
119
120     cp = strrchr (path, '/');
121     return (cp ? cp + 1 : path);
122 }
123