diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-09 22:46:06 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-09 22:46:06 +0000 |
commit | 3aba666514c8c1d6d5b21961e8f4253fd6dd2cca (patch) | |
tree | 3cbe1912235897d984fd62fdafb07b703be53209 /runit/runsv.c | |
parent | bebbd8c9baaa7a2da5ac9ab484f54ce3115982d5 (diff) | |
download | busybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.tar.gz busybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.tar.bz2 busybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.zip |
runsv: random code savings, ~300 bytes
Diffstat (limited to '')
-rw-r--r-- | runit/runsv.c | 135 |
1 files changed, 63 insertions, 72 deletions
diff --git a/runit/runsv.c b/runit/runsv.c index 4a71ae966..813709d41 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -23,20 +23,20 @@ static int selfpipe[2]; | |||
23 | 23 | ||
24 | struct svdir { | 24 | struct svdir { |
25 | int pid; | 25 | int pid; |
26 | int state; | 26 | smallint state; |
27 | int ctrl; | 27 | smallint ctrl; |
28 | int want; | 28 | smallint want; |
29 | smallint islog; | ||
29 | struct taia start; | 30 | struct taia start; |
30 | int fdlock; | 31 | int fdlock; |
31 | int fdcontrol; | 32 | int fdcontrol; |
32 | int fdcontrolwrite; | 33 | int fdcontrolwrite; |
33 | int islog; | ||
34 | }; | 34 | }; |
35 | static struct svdir svd[2]; | 35 | static struct svdir svd[2]; |
36 | 36 | ||
37 | static int sigterm = 0; | 37 | static smallint sigterm; |
38 | static int haslog = 0; | 38 | static smallint haslog; |
39 | static int pidchanged = 1; | 39 | static smallint pidchanged = 1; |
40 | static int logpipe[2]; | 40 | static int logpipe[2]; |
41 | static char *dir; | 41 | static char *dir; |
42 | 42 | ||
@@ -66,8 +66,6 @@ static void warnx_cannot(const char *m) | |||
66 | bb_error_msg("%s: warning: cannot %s", dir, m); | 66 | bb_error_msg("%s: warning: cannot %s", dir, m); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void stopservice(struct svdir *); | ||
70 | |||
71 | static void s_child(int sig_no) | 69 | static void s_child(int sig_no) |
72 | { | 70 | { |
73 | write(selfpipe[1], "", 1); | 71 | write(selfpipe[1], "", 1); |
@@ -119,17 +117,14 @@ static void update_status(struct svdir *s) | |||
119 | if (fd < 0) | 117 | if (fd < 0) |
120 | return; | 118 | return; |
121 | if (s->pid) { | 119 | if (s->pid) { |
122 | char spid[sizeof(s->pid)*3 + 2]; | 120 | char spid[sizeof(int)*3 + 2]; |
123 | int size = sprintf(spid, "%d\n", s->pid); | 121 | int size = sprintf(spid, "%u\n", (unsigned)s->pid); |
124 | write(fd, spid, size); | 122 | write(fd, spid, size); |
125 | } | 123 | } |
126 | close(fd); | 124 | close(fd); |
127 | if (s->islog) { | 125 | if (rename_or_warn("supervise/pid.new", |
128 | if (rename_or_warn("supervise/pid.new", "log/supervise/pid")) | 126 | s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) |
129 | return; | ||
130 | } else if (rename_or_warn("supervise/pid.new", "supervise/pid")) { | ||
131 | return; | 127 | return; |
132 | } | ||
133 | pidchanged = 0; | 128 | pidchanged = 0; |
134 | } | 129 | } |
135 | 130 | ||
@@ -168,11 +163,8 @@ static void update_status(struct svdir *s) | |||
168 | close(fd); | 163 | close(fd); |
169 | } | 164 | } |
170 | 165 | ||
171 | if (s->islog) { | 166 | rename_or_warn("supervise/stat.new", |
172 | rename_or_warn("supervise/stat.new", "log/supervise/stat"); | 167 | s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); |
173 | } else { | ||
174 | rename_or_warn("supervise/stat.new", "log/supervise/stat"+4); | ||
175 | } | ||
176 | 168 | ||
177 | /* supervise compatibility */ | 169 | /* supervise compatibility */ |
178 | taia_pack(status, &s->start); | 170 | taia_pack(status, &s->start); |
@@ -197,7 +189,7 @@ static void update_status(struct svdir *s) | |||
197 | fd = open_trunc_or_warn("supervise/status.new"); | 189 | fd = open_trunc_or_warn("supervise/status.new"); |
198 | if (fd < 0) | 190 | if (fd < 0) |
199 | return; | 191 | return; |
200 | l = write(fd, status, sizeof status); | 192 | l = write(fd, status, sizeof(status)); |
201 | if (l < 0) { | 193 | if (l < 0) { |
202 | warn_cannot("write supervise/status.new"); | 194 | warn_cannot("write supervise/status.new"); |
203 | close(fd); | 195 | close(fd); |
@@ -205,15 +197,12 @@ static void update_status(struct svdir *s) | |||
205 | return; | 197 | return; |
206 | } | 198 | } |
207 | close(fd); | 199 | close(fd); |
208 | if (l < sizeof status) { | 200 | if (l < sizeof(status)) { |
209 | warnx_cannot("write supervise/status.new: partial write"); | 201 | warnx_cannot("write supervise/status.new: partial write"); |
210 | return; | 202 | return; |
211 | } | 203 | } |
212 | if (s->islog) { | 204 | rename_or_warn("supervise/status.new", |
213 | rename_or_warn("supervise/status.new", "log/supervise/status"); | 205 | s->islog ? "log/supervise/status" : "log/supervise/status"+4); |
214 | } else { | ||
215 | rename_or_warn("supervise/status.new", "log/supervise/status"+4); | ||
216 | } | ||
217 | } | 206 | } |
218 | 207 | ||
219 | static unsigned custom(struct svdir *s, char c) | 208 | static unsigned custom(struct svdir *s, char c) |
@@ -225,7 +214,7 @@ static unsigned custom(struct svdir *s, char c) | |||
225 | char *prog[2]; | 214 | char *prog[2]; |
226 | 215 | ||
227 | if (s->islog) return 0; | 216 | if (s->islog) return 0; |
228 | memcpy(a, "control/?", 10); | 217 | strcpy(a, "control/?"); |
229 | a[8] = c; | 218 | a[8] = c; |
230 | if (stat(a, &st) == 0) { | 219 | if (stat(a, &st) == 0) { |
231 | if (st.st_mode & S_IXUSR) { | 220 | if (st.st_mode & S_IXUSR) { |
@@ -238,7 +227,7 @@ static unsigned custom(struct svdir *s, char c) | |||
238 | if (haslog && fd_copy(1, logpipe[1]) == -1) | 227 | if (haslog && fd_copy(1, logpipe[1]) == -1) |
239 | warn_cannot("setup stdout for control/?"); | 228 | warn_cannot("setup stdout for control/?"); |
240 | prog[0] = a; | 229 | prog[0] = a; |
241 | prog[1] = 0; | 230 | prog[1] = NULL; |
242 | execve(a, prog, environ); | 231 | execve(a, prog, environ); |
243 | fatal_cannot("run control/?"); | 232 | fatal_cannot("run control/?"); |
244 | } | 233 | } |
@@ -249,24 +238,24 @@ static unsigned custom(struct svdir *s, char c) | |||
249 | } | 238 | } |
250 | return !wait_exitcode(w); | 239 | return !wait_exitcode(w); |
251 | } | 240 | } |
252 | } | 241 | } else { |
253 | else { | 242 | if (errno != ENOENT) |
254 | if (errno == ENOENT) return 0; | 243 | warn_cannot("stat control/?"); |
255 | warn_cannot("stat control/?"); | ||
256 | } | 244 | } |
257 | return 0; | 245 | return 0; |
258 | } | 246 | } |
259 | 247 | ||
260 | static void stopservice(struct svdir *s) | 248 | static void stopservice(struct svdir *s) |
261 | { | 249 | { |
262 | if (s->pid && ! custom(s, 't')) { | 250 | if (s->pid && !custom(s, 't')) { |
263 | kill(s->pid, SIGTERM); | 251 | kill(s->pid, SIGTERM); |
264 | s->ctrl |=C_TERM; | 252 | s->ctrl |= C_TERM; |
265 | update_status(s); | 253 | update_status(s); |
266 | } | 254 | } |
267 | if (s->want == W_DOWN) { | 255 | if (s->want == W_DOWN) { |
268 | kill(s->pid, SIGCONT); | 256 | kill(s->pid, SIGCONT); |
269 | custom(s, 'd'); return; | 257 | custom(s, 'd'); |
258 | return; | ||
270 | } | 259 | } |
271 | if (s->want == W_EXIT) { | 260 | if (s->want == W_EXIT) { |
272 | kill(s->pid, SIGCONT); | 261 | kill(s->pid, SIGCONT); |
@@ -312,10 +301,7 @@ static void startservice(struct svdir *s) | |||
312 | sig_uncatch(SIGTERM); | 301 | sig_uncatch(SIGTERM); |
313 | sig_unblock(SIGTERM); | 302 | sig_unblock(SIGTERM); |
314 | execve(*run, run, environ); | 303 | execve(*run, run, environ); |
315 | if (s->islog) | 304 | fatal2_cannot(s->islog ? "start log/" : "start ", *run); |
316 | fatal2_cannot("start log/", *run); | ||
317 | else | ||
318 | fatal2_cannot("start ", *run); | ||
319 | } | 305 | } |
320 | if (s->state != S_FINISH) { | 306 | if (s->state != S_FINISH) { |
321 | taia_now(&s->start); | 307 | taia_now(&s->start); |
@@ -329,6 +315,8 @@ static void startservice(struct svdir *s) | |||
329 | 315 | ||
330 | static int ctrl(struct svdir *s, char c) | 316 | static int ctrl(struct svdir *s, char c) |
331 | { | 317 | { |
318 | int sig; | ||
319 | |||
332 | switch (c) { | 320 | switch (c) { |
333 | case 'd': /* down */ | 321 | case 'd': /* down */ |
334 | s->want = W_DOWN; | 322 | s->want = W_DOWN; |
@@ -344,23 +332,22 @@ static int ctrl(struct svdir *s, char c) | |||
344 | if (s->islog) break; | 332 | if (s->islog) break; |
345 | s->want = W_EXIT; | 333 | s->want = W_EXIT; |
346 | update_status(s); | 334 | update_status(s); |
347 | if (s->pid && s->state != S_FINISH) stopservice(s); | 335 | /* FALLTHROUGH */ |
348 | break; | ||
349 | case 't': /* sig term */ | 336 | case 't': /* sig term */ |
350 | if (s->pid && s->state != S_FINISH) stopservice(s); | 337 | if (s->pid && s->state != S_FINISH) stopservice(s); |
351 | break; | 338 | break; |
352 | case 'k': /* sig kill */ | 339 | case 'k': /* sig kill */ |
353 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGKILL); | 340 | if (s->pid && !custom(s, c)) kill(s->pid, SIGKILL); |
354 | s->state = S_DOWN; | 341 | s->state = S_DOWN; |
355 | break; | 342 | break; |
356 | case 'p': /* sig pause */ | 343 | case 'p': /* sig pause */ |
357 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGSTOP); | 344 | if (s->pid && !custom(s, c)) kill(s->pid, SIGSTOP); |
358 | s->ctrl |=C_PAUSE; | 345 | s->ctrl |= C_PAUSE; |
359 | update_status(s); | 346 | update_status(s); |
360 | break; | 347 | break; |
361 | case 'c': /* sig cont */ | 348 | case 'c': /* sig cont */ |
362 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGCONT); | 349 | if (s->pid && !custom(s, c)) kill(s->pid, SIGCONT); |
363 | if (s->ctrl & C_PAUSE) s->ctrl &=~C_PAUSE; | 350 | if (s->ctrl & C_PAUSE) s->ctrl &= ~C_PAUSE; |
364 | update_status(s); | 351 | update_status(s); |
365 | break; | 352 | break; |
366 | case 'o': /* once */ | 353 | case 'o': /* once */ |
@@ -369,25 +356,29 @@ static int ctrl(struct svdir *s, char c) | |||
369 | if (!s->pid) startservice(s); | 356 | if (!s->pid) startservice(s); |
370 | break; | 357 | break; |
371 | case 'a': /* sig alarm */ | 358 | case 'a': /* sig alarm */ |
372 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGALRM); | 359 | sig = SIGALRM; |
373 | break; | 360 | goto sendsig; |
374 | case 'h': /* sig hup */ | 361 | case 'h': /* sig hup */ |
375 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGHUP); | 362 | sig = SIGHUP; |
376 | break; | 363 | goto sendsig; |
377 | case 'i': /* sig int */ | 364 | case 'i': /* sig int */ |
378 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGINT); | 365 | sig = SIGINT; |
379 | break; | 366 | goto sendsig; |
380 | case 'q': /* sig quit */ | 367 | case 'q': /* sig quit */ |
381 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGQUIT); | 368 | sig = SIGQUIT; |
382 | break; | 369 | goto sendsig; |
383 | case '1': /* sig usr1 */ | 370 | case '1': /* sig usr1 */ |
384 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR1); | 371 | sig = SIGUSR1; |
385 | break; | 372 | goto sendsig; |
386 | case '2': /* sig usr2 */ | 373 | case '2': /* sig usr2 */ |
387 | if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR2); | 374 | sig = SIGUSR2; |
388 | break; | 375 | goto sendsig; |
389 | } | 376 | } |
390 | return 1; | 377 | return 1; |
378 | sendsig: | ||
379 | if (s->pid && !custom(s, c)) | ||
380 | kill(s->pid, sig); | ||
381 | return 1; | ||
391 | } | 382 | } |
392 | 383 | ||
393 | int runsv_main(int argc, char **argv); | 384 | int runsv_main(int argc, char **argv); |
@@ -413,12 +404,12 @@ int runsv_main(int argc, char **argv) | |||
413 | sig_catch(SIGTERM, s_term); | 404 | sig_catch(SIGTERM, s_term); |
414 | 405 | ||
415 | xchdir(dir); | 406 | xchdir(dir); |
416 | svd[0].pid = 0; | 407 | /* bss: svd[0].pid = 0; */ |
417 | svd[0].state = S_DOWN; | 408 | if (S_DOWN) svd[0].state = S_DOWN; /* otherwise already 0 (bss) */ |
418 | svd[0].ctrl = C_NOOP; | 409 | if (C_NOOP) svd[0].ctrl = C_NOOP; |
419 | svd[0].want = W_UP; | 410 | if (W_UP) svd[0].want = W_UP; |
420 | svd[0].islog = 0; | 411 | /* bss: svd[0].islog = 0; */ |
421 | svd[1].pid = 0; | 412 | /* bss: svd[1].pid = 0; */ |
422 | taia_now(&svd[0].start); | 413 | taia_now(&svd[0].start); |
423 | if (stat("down", &s) != -1) svd[0].want = W_DOWN; | 414 | if (stat("down", &s) != -1) svd[0].want = W_DOWN; |
424 | 415 | ||
@@ -445,10 +436,10 @@ int runsv_main(int argc, char **argv) | |||
445 | } | 436 | } |
446 | 437 | ||
447 | if (mkdir("supervise", 0700) == -1) { | 438 | if (mkdir("supervise", 0700) == -1) { |
448 | r = readlink("supervise", buf, 256); | 439 | r = readlink("supervise", buf, sizeof(buf)); |
449 | if (r != -1) { | 440 | if (r != -1) { |
450 | if (r == 256) | 441 | if (r == sizeof(buf)) |
451 | fatal2x_cannot("readlink ./supervise: ", "name too long"); | 442 | fatal2x_cannot("readlink ./supervise", ": name too long"); |
452 | buf[r] = 0; | 443 | buf[r] = 0; |
453 | mkdir(buf, 0700); | 444 | mkdir(buf, 0700); |
454 | } else { | 445 | } else { |
@@ -466,7 +457,7 @@ int runsv_main(int argc, char **argv) | |||
466 | r = readlink("log/supervise", buf, 256); | 457 | r = readlink("log/supervise", buf, 256); |
467 | if (r != -1) { | 458 | if (r != -1) { |
468 | if (r == 256) | 459 | if (r == 256) |
469 | fatal2x_cannot("readlink ./log/supervise: ", "name too long"); | 460 | fatal2x_cannot("readlink ./log/supervise", ": name too long"); |
470 | buf[r] = 0; | 461 | buf[r] = 0; |
471 | fd = xopen(".", O_RDONLY|O_NDELAY); | 462 | fd = xopen(".", O_RDONLY|O_NDELAY); |
472 | xchdir("./log"); | 463 | xchdir("./log"); |
@@ -552,7 +543,7 @@ int runsv_main(int argc, char **argv) | |||
552 | if (child == svd[0].pid) { | 543 | if (child == svd[0].pid) { |
553 | svd[0].pid = 0; | 544 | svd[0].pid = 0; |
554 | pidchanged = 1; | 545 | pidchanged = 1; |
555 | svd[0].ctrl &=~C_TERM; | 546 | svd[0].ctrl &=~ C_TERM; |
556 | if (svd[0].state != S_FINISH) { | 547 | if (svd[0].state != S_FINISH) { |
557 | fd = open_read("finish"); | 548 | fd = open_read("finish"); |
558 | if (fd != -1) { | 549 | if (fd != -1) { |
@@ -574,7 +565,7 @@ int runsv_main(int argc, char **argv) | |||
574 | svd[1].pid = 0; | 565 | svd[1].pid = 0; |
575 | pidchanged = 1; | 566 | pidchanged = 1; |
576 | svd[1].state = S_DOWN; | 567 | svd[1].state = S_DOWN; |
577 | svd[1].ctrl &=~C_TERM; | 568 | svd[1].ctrl &= ~C_TERM; |
578 | taia_uint(&deadline, 1); | 569 | taia_uint(&deadline, 1); |
579 | taia_add(&deadline, &svd[1].start, &deadline); | 570 | taia_add(&deadline, &svd[1].start, &deadline); |
580 | taia_now(&svd[1].start); | 571 | taia_now(&svd[1].start); |