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 | |
| 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>
| -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); |
