summaryrefslogtreecommitdiff
path: root/debianutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-07-31 17:09:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-07-31 17:09:44 +0000
commita1b16f4d5c0dd119f85f13c8cb1399a701a3e815 (patch)
treeb306578a615c33768fbd00ca05f5fbfab3787267 /debianutils
parentf1f1b69dc12d489ef8b8cd1fb4114d404407e481 (diff)
downloadbusybox-w32-a1b16f4d5c0dd119f85f13c8cb1399a701a3e815.tar.gz
busybox-w32-a1b16f4d5c0dd119f85f13c8cb1399a701a3e815.tar.bz2
busybox-w32-a1b16f4d5c0dd119f85f13c8cb1399a701a3e815.zip
start_stop_daemon: NOMMU fix; smaller fixes
Diffstat (limited to 'debianutils')
-rw-r--r--debianutils/start_stop_daemon.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 1933e1cfc..d8a0d7d46 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -8,6 +8,9 @@
8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9 */ 9 */
10 10
11/* NB: we have a problem here with /proc/NN/exe usage, similar to
12 * one fixed in killall/pidof */
13
11#include <getopt.h> 14#include <getopt.h>
12#include <sys/resource.h> 15#include <sys/resource.h>
13 16
@@ -28,33 +31,22 @@ struct pid_list {
28 31
29static struct pid_list *found; 32static struct pid_list *found;
30 33
31static inline void push(pid_t pid)
32{
33 struct pid_list *p;
34
35 p = xmalloc(sizeof(*p));
36 p->next = found;
37 p->pid = pid;
38 found = p;
39}
40
41static int pid_is_exec(pid_t pid, const char *name) 34static int pid_is_exec(pid_t pid, const char *name)
42{ 35{
43 char buf[sizeof("/proc//exe") + sizeof(int)*3]; 36 char buf[sizeof("/proc//exe") + sizeof(int)*3];
44 char *execbuf; 37 char *execbuf;
45 int sz; 38 int n;
46 int equal;
47 39
48 sprintf(buf, "/proc/%d/exe", pid); 40 sprintf(buf, "/proc/%u/exe", pid);
49 sz = strlen(name) + 1; 41 n = strlen(name) + 1;
50 execbuf = xzalloc(sz); 42 execbuf = xzalloc(n + 1);
51 readlink(buf, execbuf, sz); 43 readlink(buf, execbuf, n);
52 44
53 /* if readlink fails, execbuf still contains "" */ 45 /* if readlink fails, execbuf still contains "" */
54 equal = !strcmp(execbuf, name); 46 n = strcmp(execbuf, name);
55 if (ENABLE_FEATURE_CLEAN_UP) 47 if (ENABLE_FEATURE_CLEAN_UP)
56 free(execbuf); 48 free(execbuf);
57 return equal; 49 return ~n; /* nonzero (true) if execbuf == name */
58} 50}
59 51
60static int pid_is_user(int pid, int uid) 52static int pid_is_user(int pid, int uid)
@@ -90,9 +82,10 @@ static int pid_is_cmd(pid_t pid, const char *name)
90 return r; 82 return r;
91} 83}
92 84
93
94static void check(int pid) 85static void check(int pid)
95{ 86{
87 struct pid_list *p;
88
96 if (execname && !pid_is_exec(pid, execname)) { 89 if (execname && !pid_is_exec(pid, execname)) {
97 return; 90 return;
98 } 91 }
@@ -102,14 +95,16 @@ static void check(int pid)
102 if (cmdname && !pid_is_cmd(pid, cmdname)) { 95 if (cmdname && !pid_is_cmd(pid, cmdname)) {
103 return; 96 return;
104 } 97 }
105 push(pid); 98 p = xmalloc(sizeof(*p));
99 p->next = found;
100 p->pid = pid;
101 found = p;
106} 102}
107 103
108
109static void do_pidfile(void) 104static void do_pidfile(void)
110{ 105{
111 FILE *f; 106 FILE *f;
112 pid_t pid; 107 unsigned pid;
113 108
114 f = fopen(pidfile, "r"); 109 f = fopen(pidfile, "r");
115 if (f) { 110 if (f) {
@@ -143,10 +138,9 @@ static void do_procinit(void)
143 } 138 }
144 closedir(procdir); 139 closedir(procdir);
145 if (!foundany) 140 if (!foundany)
146 bb_error_msg_and_die ("nothing in /proc - not mounted?"); 141 bb_error_msg_and_die("nothing in /proc - not mounted?");
147} 142}
148 143
149
150static int do_stop(void) 144static int do_stop(void)
151{ 145{
152 char *what; 146 char *what;
@@ -155,11 +149,13 @@ static int do_stop(void)
155 149
156 do_procinit(); 150 do_procinit();
157 151
158 if (cmdname) 152 if (cmdname) {
159 what = xstrdup(cmdname); 153 if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname);
160 else if (execname) 154 if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname;
161 what = xstrdup(execname); 155 } else if (execname) {
162 else if (pidfile) 156 if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(execname);
157 if (!ENABLE_FEATURE_CLEAN_UP) what = execname;
158 } else if (pidfile)
163 what = xasprintf("process in pidfile '%s'", pidfile); 159 what = xasprintf("process in pidfile '%s'", pidfile);
164 else if (userspec) 160 else if (userspec)
165 what = xasprintf("process(es) owned by '%s'", userspec); 161 what = xasprintf("process(es) owned by '%s'", userspec);
@@ -169,25 +165,25 @@ static int do_stop(void)
169 if (!found) { 165 if (!found) {
170 if (!quiet) 166 if (!quiet)
171 printf("no %s found; none killed\n", what); 167 printf("no %s found; none killed\n", what);
172 if (ENABLE_FEATURE_CLEAN_UP) 168 killed = -1;
173 free(what); 169 goto ret;
174 return -1;
175 } 170 }
176 for (p = found; p; p = p->next) { 171 for (p = found; p; p = p->next) {
177 if (kill(p->pid, signal_nr) == 0) { 172 if (kill(p->pid, signal_nr) == 0) {
178 p->pid = -p->pid; 173 p->pid = - p->pid;
179 killed++; 174 killed++;
180 } else { 175 } else {
181 bb_perror_msg("warning: failed to kill %d", p->pid); 176 bb_perror_msg("warning: killing process %u", p->pid);
182 } 177 }
183 } 178 }
184 if (!quiet && killed) { 179 if (!quiet && killed) {
185 printf("stopped %s (pid", what); 180 printf("stopped %s (pid", what);
186 for (p = found; p; p = p->next) 181 for (p = found; p; p = p->next)
187 if (p->pid < 0) 182 if (p->pid < 0)
188 printf(" %d", -p->pid); 183 printf(" %u", - p->pid);
189 puts(")"); 184 puts(")");
190 } 185 }
186 ret:
191 if (ENABLE_FEATURE_CLEAN_UP) 187 if (ENABLE_FEATURE_CLEAN_UP)
192 free(what); 188 free(what);
193 return killed; 189 return killed;
@@ -287,7 +283,7 @@ int start_stop_daemon_main(int argc, char **argv)
287 283
288 if (opt & CTX_STOP) { 284 if (opt & CTX_STOP) {
289 int i = do_stop(); 285 int i = do_stop();
290 return (opt & OPT_OKNODO) ? 0 : (i<=0); 286 return (opt & OPT_OKNODO) ? 0 : (i <= 0);
291 } 287 }
292 288
293 do_procinit(); 289 do_procinit();
@@ -299,7 +295,24 @@ int start_stop_daemon_main(int argc, char **argv)
299 } 295 }
300 *--argv = startas; 296 *--argv = startas;
301 if (opt & OPT_BACKGROUND) { 297 if (opt & OPT_BACKGROUND) {
298#if BB_MMU
302 bb_daemonize(0); 299 bb_daemonize(0);
300#else
301 pid_t pid = vfork();
302 if (pid < 0) /* error */
303 bb_perror_msg_and_die("vfork");
304 if (pid == 0) /* parent */
305 return 0;
306 }
307 /* child */
308 /* Redirect stdio to /dev/null, close extra FDs.
309 * We do not actually daemonize because of DAEMON_ONLY_SANITIZE */
310 bb_daemonize_or_rexec(
311 DAEMON_DEVNULL_STDIO
312 + DAEMON_CLOSE_EXTRA_FDS
313 + DAEMON_ONLY_SANITIZE,
314 NULL /* argv, unused */ );
315#endif
303 } 316 }
304 if (opt & OPT_MAKEPID) { 317 if (opt & OPT_MAKEPID) {
305 /* user wants _us_ to make the pidfile */ 318 /* user wants _us_ to make the pidfile */