Allow /build/<checksum>
[amitay/build-farm.git] / killbysubdir.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <dirent.h>
6 #include <sys/stat.h>
7 #include <string.h>
8 #include <signal.h>
9 #include <ctype.h>
10 #ifndef PATH_MAX
11 #define PATH_MAX 1024
12 #endif
13
14 int main(int argc, char *argv[])
15 {
16         char *directory;
17         DIR *d;
18         struct dirent *de;
19         char buf[PATH_MAX];
20         size_t directory_len;
21
22         if (argc < 2) {
23                 fprintf(stderr,"%s: <directory>\n", argv[0]);
24                 exit(1);
25         }
26         
27         directory = argv[1];
28
29         /* make it absolute */
30         if (directory[0] != '/') {
31                 char *cwd = getcwd(buf, sizeof(buf));
32                 char *dir;
33                 int len;
34                 if (cwd == NULL) {
35                         perror("cwd");
36                         exit(1);
37                 }
38                 /* Add 2 for / + \0 */
39                 len = strlen(cwd) + strlen(directory) +2;
40                 dir = (char*)malloc(len * sizeof(char));
41                 sprintf(dir, "%s/%s", cwd, directory);
42                 dir[len-1] = '\0';
43                 directory = dir;
44         }
45
46         /* resolve links etc */
47         directory = realpath(directory, buf);
48
49         if (directory == NULL) {
50                 perror("realpath");
51                 exit(1);
52         }
53
54         directory_len = strlen(directory);
55         
56         d = opendir("/proc");
57         if (d == NULL) {
58                 perror("/proc");
59                 exit(1);
60         }
61
62         while ((de = readdir(d))) {
63                 const char *name = de->d_name;
64                 char *cwd_path, *real_cwd;
65                 char cwd[PATH_MAX], buf2[PATH_MAX];
66                 ssize_t link_size;
67                 int len;
68
69                 if (!isdigit(name[0])) continue;
70                 #ifdef __sun
71                 len = strlen(name) + strlen("/proc//path/cwd") + 1;
72                 cwd_path = (char*)malloc(len * sizeof(char));
73                 sprintf(cwd_path, "/proc/%s/path/cwd", name);
74                 #else
75                 len = strlen(name) + strlen("/proc//cwd") + 1;
76                 cwd_path = (char*)malloc(len * sizeof(char));
77                 sprintf(cwd_path, "/proc/%s/cwd", name);
78                 #endif
79                 cwd_path[len - 1] = '\0';
80                 link_size = readlink(cwd_path, cwd, sizeof(cwd));
81                 free(cwd_path);
82                 if (link_size == -1 || link_size >= sizeof(cwd)) {
83                         continue;
84                 }
85
86                 cwd[link_size] = '\0';
87                 real_cwd = realpath(cwd, buf2);
88                 if (real_cwd == NULL) {
89                         continue;
90                 }
91
92                 if (strncmp(directory, real_cwd, directory_len) == 0 &&
93                     (real_cwd[directory_len] == 0 || real_cwd[directory_len] == '/')) {
94                         /* kill it! */
95                         printf("Killing process %s\n", name);
96                         kill(atoi(name), SIGKILL);
97                 }
98                 
99         }
100         
101         return 0;
102 }