summaryrefslogtreecommitdiff
path: root/misc-utils/procs.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc-utils/procs.c')
-rw-r--r--misc-utils/procs.c123
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);
+}
+