strscan: make it work properly
[tools.git] / tools / spawnhunter.c
1 // Try to print the cmdlines of all process spawns by polling /proc.
2 // Doesn't do exactly what you probably need because it might catch
3 // a process between fork and exec, then ignore it.
4
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <dirent.h>
10 #include <stdio.h>
11
12
13 static unsigned int active[65536];
14
15 // assumes that *str can't be empty
16 static int str_to_int(char *str) {
17   unsigned int res = 0;
18   while (1) {
19     if (*str < '0' || *str > '9') return -1;
20     res += *str - '0';
21     str++;
22     if (*str == '\0') return res;
23     res *= 10;
24   }
25 }
26
27 int main(int argc, char *argv[]) {
28   for (int i=0; i<65536; i++) {
29     active[i] = 0;
30   }
31   
32   chdir("/proc");
33   DIR *dir = opendir(".");
34   unsigned int cycle = 2, lastcycle;
35   while (1) {
36     lastcycle = cycle-1;
37     struct dirent *dent;
38     char path[5+1+7+1];
39     while ((dent = readdir(dir)) != NULL) {
40       int name_id = str_to_int(dent->d_name);
41       if (name_id < 0 || name_id > 65535) continue;
42       if (active[name_id] != lastcycle) {
43         sprintf(path, "%s/cmdline", dent->d_name);
44         int fd = open(path, O_RDONLY);
45         if (fd != -1) {
46           char cmdline[65536];
47           int cmdline_len = read(fd, cmdline, 65536);
48           if (cmdline_len != -1) {
49             write(1, cmdline, cmdline_len);
50             write(1, "\n", 1);
51           }
52           close(fd);
53         }
54       }
55       active[name_id] = cycle;
56     }
57     rewinddir(dir);
58     cycle++;
59   }
60 }