summaryrefslogtreecommitdiff
path: root/debianutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-05-08 15:26:06 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-05-08 15:26:06 +0000
commita3087ca7495e33b19b122869d17defeb9c933d19 (patch)
treefa652fe429d78c0b2fad2c42c52c98e92bb3288d /debianutils
parent0abe9d96eee3bcdcdd766a863eb711ec004f2f4f (diff)
downloadbusybox-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.c91
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
53static int pid_is_exec(pid_t pid, const char *name) 54static 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
71static int pid_is_user(int pid, int uid) 68static 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
82static int pid_is_cmd(pid_t pid, const char *name) 79static 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
104static void check(int pid) 98static 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
253int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 252int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
254int start_stop_daemon_main(int argc, char **argv) 253int 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);