4 Copyright (C) 2006-2009 Jonathan Zarate
18 //1 (init) S 0 0 0 0 -1 256 287 10043 109 21377 7 110 473 1270 9 0 0 0 27 1810432 126 2147483647 4194304 4369680 2147450688 2147449688 717374852 0 0 0 514751 2147536844 0 0 0 0
20 char *psname(int pid
, char *buffer
, int maxlen
)
26 if (maxlen
<= 0) return NULL
;
28 sprintf(path
, "/proc/%d/stat", pid
);
29 if ((f_read_string(path
, buf
, sizeof(buf
)) > 4) && ((p
= strrchr(buf
, ')')) != NULL
)) {
31 if (((p
= strchr(buf
, '(')) != NULL
) && (atoi(buf
) == pid
)) {
32 strlcpy(buffer
, p
+ 1, maxlen
);
38 /* There is a race condition when a brand new daemon starts up using the double-fork method.
40 * There are 2 windows of vulnerability.
41 * 1) At the beginning of process startup, the new process has the wrong name, such as "init" because
42 * init forks a child which execve()'s dnsmasq, but the execve() hasn't happened yet.
43 * 2) At the end of process startup, the timing can be such that we don't see the long-lived process,
44 * only the pid(s) of the short-lived process(es), but the psname fails because they've exited by then.
46 * The 1st can be covered by a retry after a slight delay.
47 * The 2nd can be covered by a retry immediately.
49 static int _pidof(const char *name
, pid_t
**pids
)
62 if ((p
= strrchr(name
, '/')) != NULL
) name
= p
+ 1;
63 if ((dir
= opendir("/proc")) != NULL
) {
64 while ((de
= readdir(dir
)) != NULL
) {
65 i
= strtol(de
->d_name
, &e
, 10);
66 if (*e
!= 0) continue;
67 if (strcmp(name
, psname(i
, buf
, sizeof(buf
))) == 0) {
72 if ((*pids
= realloc(*pids
, sizeof(pid_t
) * (count
+ 1))) == NULL
) {
83 /* If we hit both windows, it will take three tries to discover the pid. */
84 int pidof(const char *name
)
88 p
= _pidof(name
, NULL
);
91 p
= _pidof(name
, NULL
);
93 p
= _pidof(name
, NULL
);
106 sprintf(path
, "/proc/%d/stat", pid
);
107 if ((f_read_string(path
, buf
, sizeof(buf
)) > 4))
108 sscanf(buf
, "%*d %*s %*c %d", &ppid
);
114 int killall(const char *name
, int sig
)
120 if ((i
= _pidof(name
, &pids
)) > 0) {
123 r
|= kill(pids
[--i
], sig
);