diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-15 00:24:08 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-15 00:24:08 +0200 |
commit | b3ba9e28e8796cdbba0e6e290a486706ce8bcb48 (patch) | |
tree | 4a95f7cf74cd0c33e1993e54da912325dffea219 /runit/sv.c | |
parent | e46601d8a300796b1a84a417e58ca763ec2282b7 (diff) | |
download | busybox-w32-b3ba9e28e8796cdbba0e6e290a486706ce8bcb48.tar.gz busybox-w32-b3ba9e28e8796cdbba0e6e290a486706ce8bcb48.tar.bz2 busybox-w32-b3ba9e28e8796cdbba0e6e290a486706ce8bcb48.zip |
sv: fix "sv o SRV; ...; sv d SRV" (bug 461) + code shrink
function old new delta
status 120 118 -2
control 159 126 -33
sv_main 1222 1183 -39
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'runit/sv.c')
-rw-r--r-- | runit/sv.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/runit/sv.c b/runit/sv.c index e3b9a4e31..732c33cea 100644 --- a/runit/sv.c +++ b/runit/sv.c | |||
@@ -297,8 +297,8 @@ static int status(const char *unused UNUSED_PARAM) | |||
297 | { | 297 | { |
298 | int r; | 298 | int r; |
299 | 299 | ||
300 | r = svstatus_get(); | 300 | if (svstatus_get() <= 0) |
301 | switch (r) { case -1: case 0: return 0; } | 301 | return 0; |
302 | 302 | ||
303 | r = svstatus_print(*service); | 303 | r = svstatus_print(*service); |
304 | if (chdir("log") == -1) { | 304 | if (chdir("log") == -1) { |
@@ -343,7 +343,7 @@ static int checkscript(void) | |||
343 | static int check(const char *a) | 343 | static int check(const char *a) |
344 | { | 344 | { |
345 | int r; | 345 | int r; |
346 | unsigned pid; | 346 | unsigned pid_le32; |
347 | uint64_t timestamp; | 347 | uint64_t timestamp; |
348 | 348 | ||
349 | r = svstatus_get(); | 349 | r = svstatus_get(); |
@@ -354,29 +354,29 @@ static int check(const char *a) | |||
354 | return 1; | 354 | return 1; |
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | pid = SWAP_LE32(svstatus.pid_le32); | 357 | pid_le32 = svstatus.pid_le32; |
358 | switch (*a) { | 358 | switch (*a) { |
359 | case 'x': | 359 | case 'x': |
360 | return 0; | 360 | return 0; |
361 | case 'u': | 361 | case 'u': |
362 | if (!pid || svstatus.run_or_finish != 1) return 0; | 362 | if (!pid_le32 || svstatus.run_or_finish != 1) return 0; |
363 | if (!checkscript()) return 0; | 363 | if (!checkscript()) return 0; |
364 | break; | 364 | break; |
365 | case 'd': | 365 | case 'd': |
366 | if (pid) return 0; | 366 | if (pid_le32) return 0; |
367 | break; | 367 | break; |
368 | case 'c': | 368 | case 'c': |
369 | if (pid && !checkscript()) return 0; | 369 | if (pid_le32 && !checkscript()) return 0; |
370 | break; | 370 | break; |
371 | case 't': | 371 | case 't': |
372 | if (!pid && svstatus.want == 'd') break; | 372 | if (!pid_le32 && svstatus.want == 'd') break; |
373 | timestamp = SWAP_BE64(svstatus.time_be64); | 373 | timestamp = SWAP_BE64(svstatus.time_be64); |
374 | if ((tstart > timestamp) || !pid || svstatus.got_term || !checkscript()) | 374 | if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript()) |
375 | return 0; | 375 | return 0; |
376 | break; | 376 | break; |
377 | case 'o': | 377 | case 'o': |
378 | timestamp = SWAP_BE64(svstatus.time_be64); | 378 | timestamp = SWAP_BE64(svstatus.time_be64); |
379 | if ((!pid && tstart > timestamp) || (pid && svstatus.want != 'd')) | 379 | if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd')) |
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | printf(OK); | 382 | printf(OK); |
@@ -387,12 +387,16 @@ static int check(const char *a) | |||
387 | 387 | ||
388 | static int control(const char *a) | 388 | static int control(const char *a) |
389 | { | 389 | { |
390 | int fd, r; | 390 | int fd, r, l; |
391 | 391 | ||
392 | /* Is it an optimization? | ||
393 | It causes problems with "sv o SRV; ...; sv d SRV" | ||
394 | ('d' is not passed to SRV because its .want == 'd'): | ||
392 | if (svstatus_get() <= 0) | 395 | if (svstatus_get() <= 0) |
393 | return -1; | 396 | return -1; |
394 | if (svstatus.want == *a) | 397 | if (svstatus.want == *a) |
395 | return 0; | 398 | return 0; |
399 | */ | ||
396 | fd = open_write("supervise/control"); | 400 | fd = open_write("supervise/control"); |
397 | if (fd == -1) { | 401 | if (fd == -1) { |
398 | if (errno != ENODEV) | 402 | if (errno != ENODEV) |
@@ -401,9 +405,10 @@ static int control(const char *a) | |||
401 | *a == 'x' ? ok("runsv not running") : failx("runsv not running"); | 405 | *a == 'x' ? ok("runsv not running") : failx("runsv not running"); |
402 | return -1; | 406 | return -1; |
403 | } | 407 | } |
404 | r = write(fd, a, strlen(a)); | 408 | l = strlen(a); |
409 | r = write(fd, a, l); | ||
405 | close(fd); | 410 | close(fd); |
406 | if (r != strlen(a)) { | 411 | if (r != l) { |
407 | warn("cannot write to supervise/control"); | 412 | warn("cannot write to supervise/control"); |
408 | return -1; | 413 | return -1; |
409 | } | 414 | } |
@@ -411,15 +416,12 @@ static int control(const char *a) | |||
411 | } | 416 | } |
412 | 417 | ||
413 | int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 418 | int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
414 | int sv_main(int argc, char **argv) | 419 | int sv_main(int argc UNUSED_PARAM, char **argv) |
415 | { | 420 | { |
416 | unsigned opt; | 421 | unsigned opt; |
417 | unsigned i, want_exit; | ||
418 | char *x; | 422 | char *x; |
419 | char *action; | 423 | char *action; |
420 | const char *varservice = CONFIG_SV_DEFAULT_SERVICE_DIR; | 424 | const char *varservice = CONFIG_SV_DEFAULT_SERVICE_DIR; |
421 | unsigned services; | ||
422 | char **servicex; | ||
423 | unsigned waitsec = 7; | 425 | unsigned waitsec = 7; |
424 | smallint kll = 0; | 426 | smallint kll = 0; |
425 | int verbose = 0; | 427 | int verbose = 0; |
@@ -438,12 +440,9 @@ int sv_main(int argc, char **argv) | |||
438 | 440 | ||
439 | opt_complementary = "w+:vv"; /* -w N, -v is a counter */ | 441 | opt_complementary = "w+:vv"; /* -w N, -v is a counter */ |
440 | opt = getopt32(argv, "w:v", &waitsec, &verbose); | 442 | opt = getopt32(argv, "w:v", &waitsec, &verbose); |
441 | argc -= optind; | ||
442 | argv += optind; | 443 | argv += optind; |
443 | action = *argv++; | 444 | action = *argv++; |
444 | if (!action || !*argv) bb_show_usage(); | 445 | if (!action || !*argv) bb_show_usage(); |
445 | service = argv; | ||
446 | services = argc - 1; | ||
447 | 446 | ||
448 | tnow = time(NULL) + 0x400000000000000aULL; | 447 | tnow = time(NULL) + 0x400000000000000aULL; |
449 | tstart = tnow; | 448 | tstart = tnow; |
@@ -534,20 +533,20 @@ int sv_main(int argc, char **argv) | |||
534 | bb_show_usage(); | 533 | bb_show_usage(); |
535 | } | 534 | } |
536 | 535 | ||
537 | servicex = service; | 536 | service = argv; |
538 | for (i = 0; i < services; ++i) { | 537 | while ((x = *service) != NULL) { |
539 | if ((**service != '/') && (**service != '.')) { | 538 | if (x[0] != '/' && x[0] != '.') { |
540 | if (chdir(varservice) == -1) | 539 | if (chdir(varservice) == -1) |
541 | goto chdir_failed_0; | 540 | goto chdir_failed_0; |
542 | } | 541 | } |
543 | if (chdir(*service) == -1) { | 542 | if (chdir(x) == -1) { |
544 | chdir_failed_0: | 543 | chdir_failed_0: |
545 | fail("cannot change to service directory"); | 544 | fail("cannot change to service directory"); |
546 | goto nullify_service_0; | 545 | goto nullify_service_0; |
547 | } | 546 | } |
548 | if (act && (act(acts) == -1)) { | 547 | if (act && (act(acts) == -1)) { |
549 | nullify_service_0: | 548 | nullify_service_0: |
550 | *service = NULL; | 549 | *service = (char*) -1L; /* "dead" */ |
551 | } | 550 | } |
552 | if (fchdir(curdir) == -1) | 551 | if (fchdir(curdir) == -1) |
553 | fatal_cannot("change to original directory"); | 552 | fatal_cannot("change to original directory"); |
@@ -555,19 +554,20 @@ int sv_main(int argc, char **argv) | |||
555 | } | 554 | } |
556 | 555 | ||
557 | if (cbk) while (1) { | 556 | if (cbk) while (1) { |
557 | int want_exit; | ||
558 | int diff; | 558 | int diff; |
559 | 559 | ||
560 | diff = tnow - tstart; | 560 | diff = tnow - tstart; |
561 | service = servicex; | 561 | service = argv; |
562 | want_exit = 1; | 562 | want_exit = 1; |
563 | for (i = 0; i < services; ++i, ++service) { | 563 | while ((x = *service) != NULL) { |
564 | if (!*service) | 564 | if (x == (char*) -1L) /* "dead" */ |
565 | continue; | 565 | goto next; |
566 | if ((**service != '/') && (**service != '.')) { | 566 | if (x[0] != '/' && x[0] != '.') { |
567 | if (chdir(varservice) == -1) | 567 | if (chdir(varservice) == -1) |
568 | goto chdir_failed; | 568 | goto chdir_failed; |
569 | } | 569 | } |
570 | if (chdir(*service) == -1) { | 570 | if (chdir(x) == -1) { |
571 | chdir_failed: | 571 | chdir_failed: |
572 | fail("cannot change to service directory"); | 572 | fail("cannot change to service directory"); |
573 | goto nullify_service; | 573 | goto nullify_service; |
@@ -578,17 +578,19 @@ int sv_main(int argc, char **argv) | |||
578 | if (diff >= waitsec) { | 578 | if (diff >= waitsec) { |
579 | printf(kll ? "kill: " : "timeout: "); | 579 | printf(kll ? "kill: " : "timeout: "); |
580 | if (svstatus_get() > 0) { | 580 | if (svstatus_get() > 0) { |
581 | svstatus_print(*service); | 581 | svstatus_print(x); |
582 | ++rc; | 582 | ++rc; |
583 | } | 583 | } |
584 | bb_putchar('\n'); /* will also flush the output */ | 584 | bb_putchar('\n'); /* will also flush the output */ |
585 | if (kll) | 585 | if (kll) |
586 | control("k"); | 586 | control("k"); |
587 | nullify_service: | 587 | nullify_service: |
588 | *service = NULL; | 588 | *service = (char*) -1L; /* "dead" */ |
589 | } | 589 | } |
590 | if (fchdir(curdir) == -1) | 590 | if (fchdir(curdir) == -1) |
591 | fatal_cannot("change to original directory"); | 591 | fatal_cannot("change to original directory"); |
592 | next: | ||
593 | service++; | ||
592 | } | 594 | } |
593 | if (want_exit) break; | 595 | if (want_exit) break; |
594 | usleep(420000); | 596 | usleep(420000); |