summaryrefslogtreecommitdiff
path: root/runit/sv.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-07-15 00:24:08 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-07-15 00:24:08 +0200
commitb3ba9e28e8796cdbba0e6e290a486706ce8bcb48 (patch)
tree4a95f7cf74cd0c33e1993e54da912325dffea219 /runit/sv.c
parente46601d8a300796b1a84a417e58ca763ec2282b7 (diff)
downloadbusybox-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.c68
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)
343static int check(const char *a) 343static 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
388static int control(const char *a) 388static 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
413int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 418int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
414int sv_main(int argc, char **argv) 419int 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);