]> git.sur5r.net Git - i3/i3status/blob - src/process_runs.c
clang-format-3.5 -i **/*.[ch], update modeline
[i3/i3status] / src / process_runs.c
1 // vim:ts=4:sw=4:expandtab
2 #include <stdbool.h>
3 #include <glob.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <signal.h>
10
11 #include "i3status.h"
12
13 /*
14  * Checks if the PID in path is still valid by sending signal 0 (does not do
15  * anything). kill() will return ESRCH if the process does not exist and 0 or
16  * EPERM (depending on the uid) if it exists.
17  *
18  * If multiple files match the glob pattern, all of them will be checked until
19  * the first running process is found.
20  *
21  */
22 bool process_runs(const char *path) {
23     static char pidbuf[16];
24     static glob_t globbuf;
25     memset(pidbuf, 0, sizeof(pidbuf));
26
27     if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0)
28         die("glob() failed\n");
29     if (globbuf.gl_pathc == 0) {
30         /* No glob matches, the specified path does not contain a wildcard. */
31         globfree(&globbuf);
32         if (!slurp(path, pidbuf, sizeof(pidbuf)))
33             return false;
34         return (kill(strtol(pidbuf, NULL, 10), 0) == 0 || errno == EPERM);
35     }
36     for (size_t i = 0; i < globbuf.gl_pathc; i++) {
37         if (!slurp(globbuf.gl_pathv[i], pidbuf, sizeof(pidbuf))) {
38             globfree(&globbuf);
39             return false;
40         }
41         if (kill(strtol(pidbuf, NULL, 10), 0) == 0 || errno == EPERM) {
42             globfree(&globbuf);
43             return true;
44         }
45     }
46     globfree(&globbuf);
47
48     return false;
49 }