diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-19 19:06:23 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-19 19:06:23 +0000 |
| commit | d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4 (patch) | |
| tree | 7bf3b75e143f2ba35a461604315ec93df8d0ecab /debianutils | |
| parent | 6c10657c4a4cb54ed65d797250b9a73b565c10d6 (diff) | |
| download | busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.tar.gz busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.tar.bz2 busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.zip | |
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
Diffstat (limited to 'debianutils')
| -rw-r--r-- | debianutils/start_stop_daemon.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 601fd72fa..2f8e04a78 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
| @@ -32,6 +32,7 @@ struct globals { | |||
| 32 | int user_id; | 32 | int user_id; |
| 33 | smallint quiet; | 33 | smallint quiet; |
| 34 | smallint signal_nr; | 34 | smallint signal_nr; |
| 35 | struct stat execstat; | ||
| 35 | }; | 36 | }; |
| 36 | #define G (*(struct globals*)&bb_common_bufsiz1) | 37 | #define G (*(struct globals*)&bb_common_bufsiz1) |
| 37 | #define found (G.found ) | 38 | #define found (G.found ) |
| @@ -42,6 +43,7 @@ struct globals { | |||
| 42 | #define user_id (G.user_id ) | 43 | #define user_id (G.user_id ) |
| 43 | #define quiet (G.quiet ) | 44 | #define quiet (G.quiet ) |
| 44 | #define signal_nr (G.signal_nr ) | 45 | #define signal_nr (G.signal_nr ) |
| 46 | #define execstat (G.execstat ) | ||
| 45 | #define INIT_G() \ | 47 | #define INIT_G() \ |
| 46 | do { \ | 48 | do { \ |
| 47 | user_id = -1; \ | 49 | user_id = -1; \ |
| @@ -49,22 +51,18 @@ struct globals { | |||
| 49 | } while (0) | 51 | } while (0) |
| 50 | 52 | ||
| 51 | 53 | ||
| 52 | static int pid_is_exec(pid_t pid, const char *name) | 54 | static int pid_is_exec(pid_t pid) |
| 53 | { | 55 | { |
| 56 | struct stat st; | ||
| 54 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; | 57 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; |
| 55 | char *execbuf; | ||
| 56 | int n; | ||
| 57 | 58 | ||
| 58 | sprintf(buf, "/proc/%u/exe", pid); | 59 | sprintf(buf, "/proc/%u/exe", pid); |
| 59 | n = strlen(name) + 1; | 60 | if (stat(buf, &st) < 0) |
| 60 | execbuf = xzalloc(n + 1); | 61 | return 0; |
| 61 | readlink(buf, execbuf, n); | 62 | if (st.st_dev == execstat.st_dev |
| 62 | /* if readlink fails because link target is longer than strlen(name), | 63 | && st.st_ino == execstat.st_ino) |
| 63 | * execbuf still contains "", and strcmp will return !0. */ | 64 | return 1; |
| 64 | n = strcmp(execbuf, name); | 65 | return 0; |
| 65 | if (ENABLE_FEATURE_CLEAN_UP) | ||
| 66 | free(execbuf); | ||
| 67 | return !n; /* nonzero (true) if execbuf == name */ | ||
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | static int pid_is_user(int pid, int uid) | 68 | static int pid_is_user(int pid, int uid) |
| @@ -104,7 +102,7 @@ static void check(int pid) | |||
| 104 | { | 102 | { |
| 105 | struct pid_list *p; | 103 | struct pid_list *p; |
| 106 | 104 | ||
| 107 | if (execname && !pid_is_exec(pid, execname)) { | 105 | if (execname && !pid_is_exec(pid)) { |
| 108 | return; | 106 | return; |
| 109 | } | 107 | } |
| 110 | if (userspec && !pid_is_user(pid, user_id)) { | 108 | if (userspec && !pid_is_user(pid, user_id)) { |
| @@ -300,6 +298,8 @@ int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 300 | if (errno) | 298 | if (errno) |
| 301 | user_id = xuname2uid(userspec); | 299 | user_id = xuname2uid(userspec); |
| 302 | } | 300 | } |
| 301 | if (execname) | ||
| 302 | xstat(execname, &execstat); | ||
| 303 | 303 | ||
| 304 | if (opt & CTX_STOP) { | 304 | if (opt & CTX_STOP) { |
| 305 | int i = do_stop(); | 305 | int i = do_stop(); |
