diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-08 15:26:06 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-08 15:26:06 +0000 |
commit | a3087ca7495e33b19b122869d17defeb9c933d19 (patch) | |
tree | fa652fe429d78c0b2fad2c42c52c98e92bb3288d /debianutils | |
parent | 0abe9d96eee3bcdcdd766a863eb711ec004f2f4f (diff) | |
download | busybox-w32-a3087ca7495e33b19b122869d17defeb9c933d19.tar.gz busybox-w32-a3087ca7495e33b19b122869d17defeb9c933d19.tar.bz2 busybox-w32-a3087ca7495e33b19b122869d17defeb9c933d19.zip |
Apply post-1.10.1 patches
Bump version to 1.10.2
Diffstat (limited to 'debianutils')
-rw-r--r-- | debianutils/start_stop_daemon.c | 91 |
1 files changed, 46 insertions, 45 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 6f4b6b2bb..4e816bd19 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -11,7 +11,6 @@ | |||
11 | /* NB: we have a problem here with /proc/NN/exe usage, similar to | 11 | /* NB: we have a problem here with /proc/NN/exe usage, similar to |
12 | * one fixed in killall/pidof */ | 12 | * one fixed in killall/pidof */ |
13 | 13 | ||
14 | #include <getopt.h> | ||
15 | #include <sys/resource.h> | 14 | #include <sys/resource.h> |
16 | 15 | ||
17 | /* Override ENABLE_FEATURE_PIDFILE */ | 16 | /* Override ENABLE_FEATURE_PIDFILE */ |
@@ -33,6 +32,7 @@ struct globals { | |||
33 | int user_id; | 32 | int user_id; |
34 | smallint quiet; | 33 | smallint quiet; |
35 | smallint signal_nr; | 34 | smallint signal_nr; |
35 | struct stat execstat; | ||
36 | }; | 36 | }; |
37 | #define G (*(struct globals*)&bb_common_bufsiz1) | 37 | #define G (*(struct globals*)&bb_common_bufsiz1) |
38 | #define found (G.found ) | 38 | #define found (G.found ) |
@@ -43,6 +43,7 @@ struct globals { | |||
43 | #define user_id (G.user_id ) | 43 | #define user_id (G.user_id ) |
44 | #define quiet (G.quiet ) | 44 | #define quiet (G.quiet ) |
45 | #define signal_nr (G.signal_nr ) | 45 | #define signal_nr (G.signal_nr ) |
46 | #define execstat (G.execstat ) | ||
46 | #define INIT_G() \ | 47 | #define INIT_G() \ |
47 | do { \ | 48 | do { \ |
48 | user_id = -1; \ | 49 | user_id = -1; \ |
@@ -50,25 +51,21 @@ struct globals { | |||
50 | } while (0) | 51 | } while (0) |
51 | 52 | ||
52 | 53 | ||
53 | static int pid_is_exec(pid_t pid, const char *name) | 54 | static int pid_is_exec(pid_t pid) |
54 | { | 55 | { |
56 | struct stat st; | ||
55 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; | 57 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; |
56 | char *execbuf; | ||
57 | int n; | ||
58 | 58 | ||
59 | sprintf(buf, "/proc/%u/exe", pid); | 59 | sprintf(buf, "/proc/%u/exe", pid); |
60 | n = strlen(name) + 1; | 60 | if (stat(buf, &st) < 0) |
61 | execbuf = xzalloc(n + 1); | 61 | return 0; |
62 | readlink(buf, execbuf, n); | 62 | if (st.st_dev == execstat.st_dev |
63 | /* if readlink fails because link target is longer than strlen(name), | 63 | && st.st_ino == execstat.st_ino) |
64 | * execbuf still contains "", and strcmp will return !0. */ | 64 | return 1; |
65 | n = strcmp(execbuf, name); | 65 | return 0; |
66 | if (ENABLE_FEATURE_CLEAN_UP) | ||
67 | free(execbuf); | ||
68 | return !n; /* nonzero (true) if execbuf == name */ | ||
69 | } | 66 | } |
70 | 67 | ||
71 | static int pid_is_user(int pid, int uid) | 68 | static int pid_is_user(int pid) |
72 | { | 69 | { |
73 | struct stat sb; | 70 | struct stat sb; |
74 | char buf[sizeof("/proc/") + sizeof(int)*3]; | 71 | char buf[sizeof("/proc/") + sizeof(int)*3]; |
@@ -76,42 +73,39 @@ static int pid_is_user(int pid, int uid) | |||
76 | sprintf(buf, "/proc/%u", pid); | 73 | sprintf(buf, "/proc/%u", pid); |
77 | if (stat(buf, &sb) != 0) | 74 | if (stat(buf, &sb) != 0) |
78 | return 0; | 75 | return 0; |
79 | return (sb.st_uid == uid); | 76 | return (sb.st_uid == user_id); |
80 | } | 77 | } |
81 | 78 | ||
82 | static int pid_is_cmd(pid_t pid, const char *name) | 79 | static int pid_is_cmd(pid_t pid) |
83 | { | 80 | { |
84 | char fname[sizeof("/proc//stat") + sizeof(int)*3]; | 81 | char buf[256]; /* is it big enough? */ |
85 | char *buf; | 82 | char *p, *pe; |
86 | int r = 0; | 83 | |
87 | 84 | sprintf(buf, "/proc/%u/stat", pid); | |
88 | sprintf(fname, "/proc/%u/stat", pid); | 85 | if (open_read_close(buf, buf, sizeof(buf) - 1) < 0) |
89 | buf = xmalloc_open_read_close(fname, NULL); | 86 | return 0; |
90 | if (buf) { | 87 | buf[sizeof(buf) - 1] = '\0'; /* paranoia */ |
91 | char *p = strchr(buf, '('); | 88 | p = strchr(buf, '('); |
92 | if (p) { | 89 | if (!p) |
93 | char *pe = strrchr(++p, ')'); | 90 | return 0; |
94 | if (pe) { | 91 | pe = strrchr(++p, ')'); |
95 | *pe = '\0'; | 92 | if (!pe) |
96 | r = !strcmp(p, name); | 93 | return 0; |
97 | } | 94 | *pe = '\0'; |
98 | } | 95 | return !strcmp(p, cmdname); |
99 | free(buf); | ||
100 | } | ||
101 | return r; | ||
102 | } | 96 | } |
103 | 97 | ||
104 | static void check(int pid) | 98 | static void check(int pid) |
105 | { | 99 | { |
106 | struct pid_list *p; | 100 | struct pid_list *p; |
107 | 101 | ||
108 | if (execname && !pid_is_exec(pid, execname)) { | 102 | if (execname && !pid_is_exec(pid)) { |
109 | return; | 103 | return; |
110 | } | 104 | } |
111 | if (userspec && !pid_is_user(pid, user_id)) { | 105 | if (userspec && !pid_is_user(pid)) { |
112 | return; | 106 | return; |
113 | } | 107 | } |
114 | if (cmdname && !pid_is_cmd(pid, cmdname)) { | 108 | if (cmdname && !pid_is_cmd(pid)) { |
115 | return; | 109 | return; |
116 | } | 110 | } |
117 | p = xmalloc(sizeof(*p)); | 111 | p = xmalloc(sizeof(*p)); |
@@ -148,9 +142,16 @@ static void do_procinit(void) | |||
148 | procdir = xopendir("/proc"); | 142 | procdir = xopendir("/proc"); |
149 | 143 | ||
150 | pid = 0; | 144 | pid = 0; |
151 | while ((entry = readdir(procdir)) != NULL) { | 145 | while(1) { |
146 | errno = 0; /* clear any previous error */ | ||
147 | entry = readdir(procdir); | ||
148 | // TODO: check for exact errno(s) which mean that we got stale entry | ||
149 | if (errno) /* Stale entry, process has died after opendir */ | ||
150 | continue; | ||
151 | if (!entry) /* EOF, no more entries */ | ||
152 | break; | ||
152 | pid = bb_strtou(entry->d_name, NULL, 10); | 153 | pid = bb_strtou(entry->d_name, NULL, 10); |
153 | if (errno) | 154 | if (errno) /* NaN */ |
154 | continue; | 155 | continue; |
155 | check(pid); | 156 | check(pid); |
156 | } | 157 | } |
@@ -165,8 +166,6 @@ static int do_stop(void) | |||
165 | struct pid_list *p; | 166 | struct pid_list *p; |
166 | int killed = 0; | 167 | int killed = 0; |
167 | 168 | ||
168 | do_procinit(); | ||
169 | |||
170 | if (cmdname) { | 169 | if (cmdname) { |
171 | if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname); | 170 | if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname); |
172 | if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname; | 171 | if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname; |
@@ -251,7 +250,7 @@ enum { | |||
251 | }; | 250 | }; |
252 | 251 | ||
253 | int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 252 | int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
254 | int start_stop_daemon_main(int argc, char **argv) | 253 | int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv) |
255 | { | 254 | { |
256 | unsigned opt; | 255 | unsigned opt; |
257 | char *signame; | 256 | char *signame; |
@@ -293,7 +292,7 @@ int start_stop_daemon_main(int argc, char **argv) | |||
293 | // if (retry_arg) | 292 | // if (retry_arg) |
294 | // retries = xatoi_u(retry_arg); | 293 | // retries = xatoi_u(retry_arg); |
295 | // ) | 294 | // ) |
296 | argc -= optind; | 295 | //argc -= optind; |
297 | argv += optind; | 296 | argv += optind; |
298 | 297 | ||
299 | if (userspec) { | 298 | if (userspec) { |
@@ -301,14 +300,16 @@ int start_stop_daemon_main(int argc, char **argv) | |||
301 | if (errno) | 300 | if (errno) |
302 | user_id = xuname2uid(userspec); | 301 | user_id = xuname2uid(userspec); |
303 | } | 302 | } |
303 | if (execname) | ||
304 | xstat(execname, &execstat); | ||
305 | |||
306 | do_procinit(); /* Both start and stop needs to know current processes */ | ||
304 | 307 | ||
305 | if (opt & CTX_STOP) { | 308 | if (opt & CTX_STOP) { |
306 | int i = do_stop(); | 309 | int i = do_stop(); |
307 | return (opt & OPT_OKNODO) ? 0 : (i <= 0); | 310 | return (opt & OPT_OKNODO) ? 0 : (i <= 0); |
308 | } | 311 | } |
309 | 312 | ||
310 | do_procinit(); | ||
311 | |||
312 | if (found) { | 313 | if (found) { |
313 | if (!quiet) | 314 | if (!quiet) |
314 | printf("%s already running\n%d\n", execname, found->pid); | 315 | printf("%s already running\n%d\n", execname, found->pid); |