start-stop-daemon: make --exec follow symlinks

by Joakim Tjernlund <joakim.tjernlund AT transmode.se>

function                                             old     new   delta
check                                               1591    1618     +27
start_stop_daemon_main                               770     792     +22
This commit is contained in:
Denis Vlasenko 2008-04-19 19:06:23 +00:00
parent 6c10657c4a
commit d9c51e9fa7

View File

@ -32,6 +32,7 @@ struct globals {
int user_id; int user_id;
smallint quiet; smallint quiet;
smallint signal_nr; smallint signal_nr;
struct stat execstat;
}; };
#define G (*(struct globals*)&bb_common_bufsiz1) #define G (*(struct globals*)&bb_common_bufsiz1)
#define found (G.found ) #define found (G.found )
@ -42,6 +43,7 @@ struct globals {
#define user_id (G.user_id ) #define user_id (G.user_id )
#define quiet (G.quiet ) #define quiet (G.quiet )
#define signal_nr (G.signal_nr ) #define signal_nr (G.signal_nr )
#define execstat (G.execstat )
#define INIT_G() \ #define INIT_G() \
do { \ do { \
user_id = -1; \ user_id = -1; \
@ -49,22 +51,18 @@ struct globals {
} while (0) } while (0)
static int pid_is_exec(pid_t pid, const char *name) static int pid_is_exec(pid_t pid)
{ {
struct stat st;
char buf[sizeof("/proc//exe") + sizeof(int)*3]; char buf[sizeof("/proc//exe") + sizeof(int)*3];
char *execbuf;
int n;
sprintf(buf, "/proc/%u/exe", pid); sprintf(buf, "/proc/%u/exe", pid);
n = strlen(name) + 1; if (stat(buf, &st) < 0)
execbuf = xzalloc(n + 1); return 0;
readlink(buf, execbuf, n); if (st.st_dev == execstat.st_dev
/* if readlink fails because link target is longer than strlen(name), && st.st_ino == execstat.st_ino)
* execbuf still contains "", and strcmp will return !0. */ return 1;
n = strcmp(execbuf, name); return 0;
if (ENABLE_FEATURE_CLEAN_UP)
free(execbuf);
return !n; /* nonzero (true) if execbuf == name */
} }
static int pid_is_user(int pid, int uid) static int pid_is_user(int pid, int uid)
@ -104,7 +102,7 @@ static void check(int pid)
{ {
struct pid_list *p; struct pid_list *p;
if (execname && !pid_is_exec(pid, execname)) { if (execname && !pid_is_exec(pid)) {
return; return;
} }
if (userspec && !pid_is_user(pid, user_id)) { if (userspec && !pid_is_user(pid, user_id)) {
@ -300,6 +298,8 @@ int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv)
if (errno) if (errno)
user_id = xuname2uid(userspec); user_id = xuname2uid(userspec);
} }
if (execname)
xstat(execname, &execstat);
if (opt & CTX_STOP) { if (opt & CTX_STOP) {
int i = do_stop(); int i = do_stop();