diff options
Diffstat (limited to 'misc-utils/procs.c')
-rw-r--r-- | misc-utils/procs.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/misc-utils/procs.c b/misc-utils/procs.c new file mode 100644 index 0000000..3f52387 --- /dev/null +++ b/misc-utils/procs.c @@ -0,0 +1,123 @@ +/* + * procs.c -- functions to parse the linux /proc filesystem. + * (c) 1994 salvatore valente <svalente@mit.edu> + * + * this program is free software. you can redistribute it and + * modify it under the terms of the gnu general public license. + * there is no warranty. + * + * faith + * 1.2 + * 1995/02/23 01:20:40 + * + */ + +#define _POSIX_SOURCE 1 + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <ctype.h> +#include <unistd.h> +#include "kill.h" + +extern char *mybasename (char *); +static char *parse_parens (char *buf); + +int * +get_pids (char *process_name, int get_all) { + DIR *dir; + struct dirent *ent; + int status; + char *dname, fname[100], *cp, buf[256]; + struct stat st; + uid_t uid; + FILE *fp; + int pid, *pids, num_pids, pids_size; + + dir = opendir ("/proc"); + if (! dir) { + perror ("opendir /proc"); + return NULL; + } + uid = getuid (); + pids = NULL; + num_pids = pids_size = 0; + + while ((ent = readdir (dir)) != NULL) { + dname = ent->d_name; + if (! isdigit (*dname)) continue; + pid = atoi (dname); + sprintf (fname, "/proc/%d/cmdline", pid); + /* get the process owner */ + status = stat (fname, &st); + if (status != 0) continue; + if (! get_all && uid != st.st_uid) continue; + /* get the command line */ + fp = fopen (fname, "r"); + if (! fp) continue; + cp = fgets (buf, sizeof (buf), fp); + fclose (fp); + /* an empty command line means the process is swapped out */ + if (! cp || ! *cp) { + /* get the process name from the statfile */ + sprintf (fname, "/proc/%d/stat", pid); + fp = fopen (fname, "r"); + if (! fp) continue; + cp = fgets (buf, sizeof (buf), fp); + if (cp == NULL) continue; + fclose (fp); + cp = parse_parens (buf); + if (cp == NULL) continue; + } + /* ok, we got the process name. */ + if (strcmp (process_name, mybasename (cp))) continue; + while (pids_size < num_pids + 2) { + pids_size += 5; + pids = (int *) realloc (pids, sizeof (int) * pids_size); + } + pids[num_pids++] = pid; + pids[num_pids] = -1; + } + closedir (dir); + return (pids); +} + +/* + * parse_parens () -- return an index just past the first open paren in + * buf, and terminate the string at the matching close paren. + */ +static char *parse_parens (char *buf) +{ + char *cp, *ip; + int depth; + + cp = strchr (buf, '('); + if (cp == NULL) return NULL; + cp++; + depth = 1; + for (ip = cp; *ip; ip++) { + if (*ip == '(') + depth++; + if (*ip == ')') { + depth--; + if (depth == 0) { + *ip = 0; + break; + } + } + } + return cp; +} + +char *mybasename (char *path) +{ + char *cp; + + cp = strrchr (path, '/'); + return (cp ? cp + 1 : path); +} + |