Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/runit/sv.c


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/runit/sv.c

    r1765 r2725  
    151151*/
    152152
    153 /* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
     153/* Busyboxed by Denys Vlasenko <vda.linux@googlemail.com> */
    154154/* TODO: depends on runit_lib.c - review and reduce/eliminate */
    155155
     
    159159#include "runit_lib.h"
    160160
    161 static const char *acts;
    162 static char **service;
    163 static unsigned rc;
     161struct globals {
     162    const char *acts;
     163    char **service;
     164    unsigned rc;
    164165/* "Bernstein" time format: unix + 0x400000000000000aULL */
    165 static uint64_t tstart, tnow;
    166 svstatus_t svstatus;
    167 
    168 
    169 static void fatal_cannot(const char *m1) ATTRIBUTE_NORETURN;
     166    uint64_t tstart, tnow;
     167    svstatus_t svstatus;
     168} FIX_ALIASING;
     169#define G (*(struct globals*)&bb_common_bufsiz1)
     170#define acts         (G.acts        )
     171#define service      (G.service     )
     172#define rc           (G.rc          )
     173#define tstart       (G.tstart      )
     174#define tnow         (G.tnow        )
     175#define svstatus     (G.svstatus    )
     176#define INIT_G() do { } while (0)
     177
     178
     179#define str_equal(s,t) (!strcmp((s), (t)))
     180
     181
     182static void fatal_cannot(const char *m1) NORETURN;
    170183static void fatal_cannot(const char *m1)
    171184{
    172     bb_perror_msg("fatal: cannot %s", m1);
     185    bb_perror_msg("fatal: can't %s", m1);
    173186    _exit(151);
    174187}
     
    180193        printf(": %s", strerror(errno));
    181194    }
    182     puts(""); /* will also flush the output */
     195    bb_putchar('\n'); /* will also flush the output */
    183196}
    184197
     
    212225    int fd, r;
    213226
    214     fd = open_write("supervise/ok");
     227    fd = open("supervise/ok", O_WRONLY|O_NDELAY);
    215228    if (fd == -1) {
    216229        if (errno == ENODEV) {
     
    219232            return 0;
    220233        }
    221         warn("cannot open supervise/ok");
     234        warn("can't open supervise/ok");
    222235        return -1;
    223236    }
    224237    close(fd);
    225     fd = open_read("supervise/status");
     238    fd = open("supervise/status", O_RDONLY|O_NDELAY);
    226239    if (fd == -1) {
    227         warn("cannot open supervise/status");
     240        warn("can't open supervise/status");
    228241        return -1;
    229242    }
     
    234247        break;
    235248    case -1:
    236         warn("cannot read supervise/status");
     249        warn("can't read supervise/status");
    237250        return -1;
    238251    default:
    239252        errno = 0;
    240         warn("cannot read supervise/status: bad format");
     253        warn("can't read supervise/status: bad format");
    241254        return -1;
    242255    }
     
    254267    if (stat("down", &s) == -1) {
    255268        if (errno != ENOENT) {
    256             bb_perror_msg(WARN"cannot stat %s/down", *service);
     269            bb_perror_msg(WARN"can't stat %s/down", *service);
    257270            return 0;
    258271        }
     
    284297}
    285298
    286 static int status(const char *unused)
     299static int status(const char *unused UNUSED_PARAM)
    287300{
    288301    int r;
    289302
    290     r = svstatus_get();
    291     switch (r) { case -1: case 0: return 0; }
     303    if (svstatus_get() <= 0)
     304        return 0;
    292305
    293306    r = svstatus_print(*service);
    294307    if (chdir("log") == -1) {
    295308        if (errno != ENOENT) {
    296             printf("; log: "WARN"cannot change to log service directory: %s",
     309            printf("; log: "WARN"can't change to log service directory: %s",
    297310                    strerror(errno));
    298311        }
     
    301314        svstatus_print("log");
    302315    }
    303     puts(""); /* will also flush the output */
     316    bb_putchar('\n'); /* will also flush the output */
    304317    return r;
    305318}
     
    313326    if (stat("check", &s) == -1) {
    314327        if (errno == ENOENT) return 1;
    315         bb_perror_msg(WARN"cannot stat %s/check", *service);
     328        bb_perror_msg(WARN"can't stat %s/check", *service);
    316329        return 0;
    317330    }
     
    321334    pid = spawn(prog);
    322335    if (pid <= 0) {
    323         bb_perror_msg(WARN"cannot %s child %s/check", "run", *service);
     336        bb_perror_msg(WARN"can't %s child %s/check", "run", *service);
    324337        return 0;
    325338    }
    326     while (wait_pid(&w, pid) == -1) {
    327         if (errno == EINTR) continue;
    328         bb_perror_msg(WARN"cannot %s child %s/check", "wait for", *service);
     339    while (safe_waitpid(pid, &w, 0) == -1) {
     340        bb_perror_msg(WARN"can't %s child %s/check", "wait for", *service);
    329341        return 0;
    330342    }
    331     return !wait_exitcode(w);
     343    return WEXITSTATUS(w) == 0;
    332344}
    333345
     
    335347{
    336348    int r;
    337     unsigned pid;
     349    unsigned pid_le32;
    338350    uint64_t timestamp;
    339351
     
    346358        return -1;
    347359    }
    348     pid = SWAP_LE32(svstatus.pid_le32);
     360    pid_le32 = svstatus.pid_le32;
    349361    switch (*a) {
    350362    case 'x':
    351363        return 0;
    352364    case 'u':
    353         if (!pid || svstatus.run_or_finish != 1) return 0;
     365        if (!pid_le32 || svstatus.run_or_finish != 1) return 0;
    354366        if (!checkscript()) return 0;
    355367        break;
    356368    case 'd':
    357         if (pid) return 0;
     369        if (pid_le32) return 0;
    358370        break;
    359371    case 'c':
    360         if (pid && !checkscript()) return 0;
     372        if (pid_le32 && !checkscript()) return 0;
    361373        break;
    362374    case 't':
    363         if (!pid && svstatus.want == 'd') break;
     375        if (!pid_le32 && svstatus.want == 'd') break;
    364376        timestamp = SWAP_BE64(svstatus.time_be64);
    365         if ((tstart > timestamp) || !pid || svstatus.got_term || !checkscript())
     377        if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript())
    366378            return 0;
    367379        break;
    368380    case 'o':
    369381        timestamp = SWAP_BE64(svstatus.time_be64);
    370         if ((!pid && tstart > timestamp) || (pid && svstatus.want != 'd'))
     382        if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd'))
    371383            return 0;
    372384    }
    373385    printf(OK);
    374386    svstatus_print(*service);
    375     puts(""); /* will also flush the output */
     387    bb_putchar('\n'); /* will also flush the output */
    376388    return 1;
    377389}
     
    379391static int control(const char *a)
    380392{
    381     int fd, r;
    382 
     393    int fd, r, l;
     394
     395/* Is it an optimization?
     396   It causes problems with "sv o SRV; ...; sv d SRV"
     397   ('d' is not passed to SRV because its .want == 'd'):
    383398    if (svstatus_get() <= 0)
    384399        return -1;
    385400    if (svstatus.want == *a)
    386401        return 0;
    387     fd = open_write("supervise/control");
     402*/
     403    fd = open("supervise/control", O_WRONLY|O_NDELAY);
    388404    if (fd == -1) {
    389405        if (errno != ENODEV)
    390             warn("cannot open supervise/control");
     406            warn("can't open supervise/control");
    391407        else
    392408            *a == 'x' ? ok("runsv not running") : failx("runsv not running");
    393409        return -1;
    394410    }
    395     r = write(fd, a, strlen(a));
     411    l = strlen(a);
     412    r = write(fd, a, l);
    396413    close(fd);
    397     if (r != strlen(a)) {
    398         warn("cannot write to supervise/control");
     414    if (r != l) {
     415        warn("can't write to supervise/control");
    399416        return -1;
    400417    }
     
    402419}
    403420
    404 int sv_main(int argc, char **argv);
    405 int sv_main(int argc, char **argv)
     421int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     422int sv_main(int argc UNUSED_PARAM, char **argv)
    406423{
    407424    unsigned opt;
    408     unsigned i, want_exit;
    409425    char *x;
    410426    char *action;
    411     const char *varservice = "/var/service/";
    412     unsigned services;
    413     char **servicex;
     427    const char *varservice = CONFIG_SV_DEFAULT_SERVICE_DIR;
    414428    unsigned waitsec = 7;
    415429    smallint kll = 0;
    416     smallint verbose = 0;
     430    int verbose = 0;
    417431    int (*act)(const char*);
    418432    int (*cbk)(const char*);
    419433    int curdir;
     434
     435    INIT_G();
    420436
    421437    xfunc_error_retval = 100;
     
    426442    if (x) waitsec = xatou(x);
    427443
    428     opt = getopt32(argv, "w:v", &x);
    429     if (opt & 1) waitsec = xatou(x); // -w
    430     if (opt & 2) verbose = 1; // -v
    431     argc -= optind;
     444    opt_complementary = "w+:vv"; /* -w N, -v is a counter */
     445    opt = getopt32(argv, "w:v", &waitsec, &verbose);
    432446    argv += optind;
    433447    action = *argv++;
    434448    if (!action || !*argv) bb_show_usage();
    435     service = argv;
    436     services = argc - 1;
    437 
    438     tnow = time(0) + 0x400000000000000aULL;
     449
     450    tnow = time(NULL) + 0x400000000000000aULL;
    439451    tstart = tnow;
    440     curdir = open_read(".");
     452    curdir = open(".", O_RDONLY|O_NDELAY);
    441453    if (curdir == -1)
    442454        fatal_cannot("open current directory");
     
    525537    }
    526538
    527     servicex = service;
    528     for (i = 0; i < services; ++i) {
    529         if ((**service != '/') && (**service != '.')) {
     539    service = argv;
     540    while ((x = *service) != NULL) {
     541        if (x[0] != '/' && x[0] != '.') {
    530542            if (chdir(varservice) == -1)
    531543                goto chdir_failed_0;
    532544        }
    533         if (chdir(*service) == -1) {
     545        if (chdir(x) == -1) {
    534546 chdir_failed_0:
    535             fail("cannot change to service directory");
     547            fail("can't change to service directory");
    536548            goto nullify_service_0;
    537549        }
    538550        if (act && (act(acts) == -1)) {
    539551 nullify_service_0:
    540             *service = NULL;
     552            *service = (char*) -1L; /* "dead" */
    541553        }
    542554        if (fchdir(curdir) == -1)
     
    546558
    547559    if (cbk) while (1) {
     560        int want_exit;
    548561        int diff;
    549562
    550563        diff = tnow - tstart;
    551         service = servicex;
     564        service = argv;
    552565        want_exit = 1;
    553         for (i = 0; i < services; ++i, ++service) {
    554             if (!*service)
    555                 continue;
    556             if ((**service != '/') && (**service != '.')) {
     566        while ((x = *service) != NULL) {
     567            if (x == (char*) -1L) /* "dead" */
     568                goto next;
     569            if (x[0] != '/' && x[0] != '.') {
    557570                if (chdir(varservice) == -1)
    558571                    goto chdir_failed;
    559572            }
    560             if (chdir(*service) == -1) {
     573            if (chdir(x) == -1) {
    561574 chdir_failed:
    562                 fail("cannot change to service directory");
     575                fail("can't change to service directory");
    563576                goto nullify_service;
    564577            }
     
    569582                printf(kll ? "kill: " : "timeout: ");
    570583                if (svstatus_get() > 0) {
    571                     svstatus_print(*service);
     584                    svstatus_print(x);
    572585                    ++rc;
    573586                }
    574                 puts(""); /* will also flush the output */
     587                bb_putchar('\n'); /* will also flush the output */
    575588                if (kll)
    576589                    control("k");
    577590 nullify_service:
    578                 *service = NULL;
     591                *service = (char*) -1L; /* "dead" */
    579592            }
    580593            if (fchdir(curdir) == -1)
    581594                fatal_cannot("change to original directory");
     595 next:
     596            service++;
    582597        }
    583598        if (want_exit) break;
    584599        usleep(420000);
    585         tnow = time(0) + 0x400000000000000aULL;
     600        tnow = time(NULL) + 0x400000000000000aULL;
    586601    }
    587602    return rc > 99 ? 99 : rc;
Note: See TracChangeset for help on using the changeset viewer.