diff --git a/.gitignore b/.gitignore index ded7be7..3871e64 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ haswaitp.h installer iopause.h load +makefifo makelib matchtest multilog diff --git a/envdir.c b/envdir.c index f02e739..dddd3c9 100644 --- a/envdir.c +++ b/envdir.c @@ -71,14 +71,14 @@ int main(int argc,const char *const *argv) if (sa.len) { sa.len = byte_chr(sa.s,sa.len,'\n'); while (sa.len) { - if (sa.s[sa.len - 1] != ' ') - if (sa.s[sa.len - 1] != '\t') - break; - --sa.len; + if (sa.s[sa.len - 1] != ' ') + if (sa.s[sa.len - 1] != '\t') + break; + --sa.len; } for (i = 0;i < sa.len;++i) - if (!sa.s[i]) - sa.s[i] = '\n'; + if (!sa.s[i]) + sa.s[i] = '\n'; if (!stralloc_0(&sa)) nomem(); if (!pathexec_env(saname.s,sa.s)) nomem(); } diff --git a/envini.c b/envini.c index 3054e90..5d68c1f 100644 --- a/envini.c +++ b/envini.c @@ -47,28 +47,28 @@ static void parse(void) ++start; if (end > start) { if (sa.s[start] == '[' && sa.s[end-1] == ']') { - if (!stralloc_copyb(§ion,sa.s+start+1,end-start-2)) nomem(); - if (!stralloc_append(§ion,'_')) nomem(); + if (!stralloc_copyb(§ion,sa.s+start+1,end-start-2)) nomem(); + if (!stralloc_append(§ion,'_')) nomem(); } else if (sa.s[start] == ';') - ; + ; else { - i = start; - while (i < end && sa.s[i] != '=' && !is_space(sa.s[i])) - ++i; - if (!stralloc_copys(&name,prefix)) nomem(); - if (!stralloc_cat(&name,§ion)) nomem(); - if (!stralloc_catb(&name,sa.s+start,i-start)) nomem(); - if (!stralloc_0(&name)) nomem(); - while (i < end && is_space(sa.s[i])) - ++i; - if (i >= end || sa.s[i++] != '=') - continue; /* Ignore misformatted lines */ - while (i < end && is_space(sa.s[i])) - ++i; - if (!stralloc_copyb(&value,sa.s+i,end-i)) nomem(); - if (!stralloc_0(&value)) nomem(); - if (!pathexec_env(name.s,value.s)) nomem(); + i = start; + while (i < end && sa.s[i] != '=' && !is_space(sa.s[i])) + ++i; + if (!stralloc_copys(&name,prefix)) nomem(); + if (!stralloc_cat(&name,§ion)) nomem(); + if (!stralloc_catb(&name,sa.s+start,i-start)) nomem(); + if (!stralloc_0(&name)) nomem(); + while (i < end && is_space(sa.s[i])) + ++i; + if (i >= end || sa.s[i++] != '=') + continue; /* Ignore misformatted lines */ + while (i < end && is_space(sa.s[i])) + ++i; + if (!stralloc_copyb(&value,sa.s+i,end-i)) nomem(); + if (!stralloc_0(&value)) nomem(); + if (!pathexec_env(name.s,value.s)) nomem(); } } } @@ -81,8 +81,8 @@ int main(int argc,const char *const *argv) while ((opt = getopt(argc,argv,"p:")) != opteof) switch (opt) { - case 'p': prefix = optarg; break; - default: die_usage(); + case 'p': prefix = optarg; break; + default: die_usage(); } argv += optind; diff --git a/installer.c b/installer.c index e579cec..3de6f6a 100644 --- a/installer.c +++ b/installer.c @@ -94,36 +94,36 @@ void doit(stralloc *line) case 'd': if (mkdir(target.s,0700) == -1) if (errno != error_exist) - strerr_die3sys(111,FATAL,"unable to mkdir ",target.s); + strerr_die3sys(111,FATAL,"unable to mkdir ",target.s); break; case 'c': fdin = open_read(name); if (fdin == -1) { - if (opt) - return; - else - strerr_die3sys(111,FATAL,"unable to read ",name); + if (opt) + return; + else + strerr_die3sys(111,FATAL,"unable to read ",name); } buffer_init(&bufin,buffer_unixread,fdin,inbuf,sizeof(inbuf)); fdout = open_trunc(target.s); if (fdout == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); buffer_init(&bufout,buffer_unixwrite,fdout,outbuf,sizeof(outbuf)); switch(buffer_copy(&bufout,&bufin)) { - case -2: - strerr_die3sys(111,FATAL,"unable to read ",name); - case -3: - strerr_die3sys(111,FATAL,"unable to write ",target.s); + case -2: + strerr_die3sys(111,FATAL,"unable to read ",name); + case -3: + strerr_die3sys(111,FATAL,"unable to write ",target.s); } close(fdin); if (buffer_flush(&bufout) == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); if (fsync(fdout) == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); close(fdout); break; diff --git a/makefifo.c b/makefifo.c new file mode 100644 index 0000000..9b689d5 --- /dev/null +++ b/makefifo.c @@ -0,0 +1,35 @@ +#include "alloc.h" +#include "fifo.h" +#include "stralloc.h" +#include "strerr.h" + +#define FATAL "makefifo: fatal: " +#define WARNING "makefifo: warning: " + +static void die_usage(void) +{ + strerr_die1x(100,"makefifo: usage: makefifo fifo1 [fifo2 ...]"); +} + +static void die_nomem(void) +{ + strerr_die2sys(100,FATAL,"out of memory"); +} + +int main(int argc, char **argv) +{ + stralloc fn = {0,0,0}; + int i; + + if (argc < 2) die_usage(); + + for (i = 1;i < argc; ++i) { + if (!stralloc_copys(&fn,argv[i])) die_nomem(); + if (!stralloc_0(&fn)) die_nomem(); + if (fifo_make(fn.s,0600)) + strerr_warn3sys(WARNING,"can't make fifo ",fn.s); + } + + alloc_free(fn.s); + return 0; +} diff --git a/makefifo=x b/makefifo=x new file mode 100644 index 0000000..09db56a --- /dev/null +++ b/makefifo=x @@ -0,0 +1,2 @@ +unix.a +byte.a diff --git a/multilog.c b/multilog.c index 464bb39..dca386e 100644 --- a/multilog.c +++ b/multilog.c @@ -136,8 +136,8 @@ int filesfit(struct cyclog *d) if (x->d_name[0] == '@') if (str_len(x->d_name) >= 25) if (str_start(x->d_name,fn.s)) { - unlink(x->d_name); - break; + unlink(x->d_name); + break; } } if (errno) { closedir(dir); return -1; } @@ -161,7 +161,7 @@ void finish(struct cyclog *d,const char *file,const char *code) fnlen = fmt_tai64nstamp(fn.s); fn.s[fnlen++] = '.'; do { - fn.s[fnlen++] = *code; + fn.s[fnlen++] = *code; } while (*code++ != 0); if (link(file,fn.s) == 0) break; @@ -419,7 +419,7 @@ void c_init(char **script) else if (script[i][0] == 'w') { code_finished = script[i] + 1; if (!stralloc_ready(&fn,str_len(code_finished)+TIMESTAMP+1)) - strerr_die2sys(111,FATAL,"unable to allocate memory"); + strerr_die2sys(111,FATAL,"unable to allocate memory"); } else if ((script[i][0] == '.') || (script[i][0] == '/')) { d->num = num; @@ -469,7 +469,7 @@ int flushread(int fd,char *buf,int len) if (flagforcerotate) { for (j = 0;j < cnum;++j) if (c[j].bytes > 0) - fullcurrent(&c[j]); + fullcurrent(&c[j]); flagforcerotate = 0; } @@ -524,8 +524,8 @@ void doit(char **script) return; if (flagtimestamp) { linelen = (flagtimestamp == 't') - ? fmt_tai64nstamp(line) - : fmt_accustamp(line); + ? fmt_tai64nstamp(line) + : fmt_accustamp(line); line[linelen++] = ' '; } if (buffer_gets(&ssin,line+linelen,MAXLINE-linelen,'\n',&linelen) < 0) @@ -538,11 +538,11 @@ void doit(char **script) for (i = 0;(action = script[i]) != 0;++i) switch(*action) { case 'F': - match = match_fnmatch; - break; + match = match_fnmatch; + break; case 'S': - match = match_simple; - break; + match = match_simple; + break; case '+': if (!flagselected) if (match(action + 1,line,linelen)) @@ -590,19 +590,19 @@ void doit(char **script) while (linelen == MAXLINE) { linelen = 0; if (buffer_gets(&ssin,line,MAXLINE,'\n',&linelen) < 0) { - flageof = 1; - break; + flageof = 1; + break; } if (linelen == 0) - break; + break; for (j = 0;j < cnum;++j) - if (c[j].flagselected) - buffer_put(&c[j].ss,line,linelen); + if (c[j].flagselected) + buffer_put(&c[j].ss,line,linelen); } for (j = 0;j < cnum;++j) if (c[j].flagselected) { - ch = '\n'; + ch = '\n'; buffer_PUTC(&c[j].ss,ch); } diff --git a/pathexec_env.c b/pathexec_env.c index 2cb101c..0779c75 100644 --- a/pathexec_env.c +++ b/pathexec_env.c @@ -52,14 +52,14 @@ void pathexec(const char *const *argv) if (!plus.s[i]) { split = str_chr(plus.s + j,'='); for (t = 0;t < elen;++t) - if (byte_equal(plus.s + j,split,e[t])) - if (e[t][split] == '=') { - --elen; - e[t] = e[elen]; - break; - } + if (byte_equal(plus.s + j,split,e[t])) + if (e[t][split] == '=') { + --elen; + e[t] = e[elen]; + break; + } if (plus.s[j + split]) - e[elen++] = plus.s + j; + e[elen++] = plus.s + j; j = i + 1; } e[elen] = 0; diff --git a/programs.do b/programs.do index f635648..0a6bbd4 100644 --- a/programs.do +++ b/programs.do @@ -1,3 +1,4 @@ -dependon envdir envini envuidgid fghack installer matchtest multilog pgrphack \ - readproctitle setlock setuidgid setuser sleeper softlimit supervise svc \ - svok svscan svscanboot svstat svup tai64n tai64nlocal +dependon envdir envini envuidgid fghack installer makefifo matchtest \ + multilog pgrphack readproctitle setlock setuidgid setuser \ + sleeper softlimit supervise svc svok svscan svscanboot svstat \ + svup tai64n tai64nlocal diff --git a/readproctitle.c b/readproctitle.c index 82fbffd..0203a6c 100644 --- a/readproctitle.c +++ b/readproctitle.c @@ -17,14 +17,14 @@ int main(int argc,char **argv) for (;;) switch(read(0,&ch,1)) { case 1: - if (ch) { - for (i = 4;i < len;++i) buf[i - 1] = buf[i]; - buf[len - 1] = ch; - } - break; + if (ch) { + for (i = 4;i < len;++i) buf[i - 1] = buf[i]; + buf[len - 1] = ch; + } + break; case 0: - _exit(0); + _exit(0); case -1: - if (errno != error_intr) _exit(111); + if (errno != error_intr) _exit(111); } } diff --git a/rts.tests/10-makefifo.exp b/rts.tests/10-makefifo.exp new file mode 100644 index 0000000..bb0a528 --- /dev/null +++ b/rts.tests/10-makefifo.exp @@ -0,0 +1,35 @@ +--- makefifo works +makefifo: warning: can't make fifo fifo0: file already exists +makefifo: warning: can't make fifo fifo1: file already exists +makefifo: warning: can't make fifo fifo2: file already exists +makefifo: warning: can't make fifo fifo3: file already exists +makefifo: warning: can't make fifo fifo4: file already exists +makefifo: warning: can't make fifo fifo5: file already exists +makefifo: warning: can't make fifo fifo6: file already exists +makefifo: warning: can't make fifo fifo7: file already exists +makefifo: warning: can't make fifo fifo8: file already exists +makefifo: warning: can't make fifo fifo9: file already exists +makefifo: warning: can't make fifo fifoA: file already exists +makefifo: warning: can't make fifo fifoB: file already exists +makefifo: warning: can't make fifo fifoC: file already exists +makefifo: warning: can't make fifo fifoD: file already exists +makefifo: warning: can't make fifo fifoE: file already exists +makefifo: warning: can't make fifo fifoF: file already exists +makefifo: warning: can't make fifo fifo0: file already exists +makefifo: usage: makefifo fifo1 [fifo2 ...] +ok 0 +ok 1 +ok 2 +ok 3 +ok 4 +ok 5 +ok 6 +ok 7 +ok 8 +ok 9 +ok A +ok B +ok C +ok D +ok E +ok F diff --git a/rts.tests/10-makefifo.sh b/rts.tests/10-makefifo.sh new file mode 100644 index 0000000..7f6380b --- /dev/null +++ b/rts.tests/10-makefifo.sh @@ -0,0 +1,35 @@ +echo '--- makefifo works' +rm -rf makefifo +mkdir makefifo +cd makefifo +makefifo fifo0 fifo1 fifo2 +makefifo fifo3 fifo4 fifo0 +makefifo fifo5 fifo6 +makefifo fifo7 fifo1 fifo8 +makefifo fifo9 fifo2 fifo3 +makefifo fifoA fifo4 +makefifo fifo5 fifoB fifoC +makefifo fifo6 fifoD fifo7 +makefifo fifo8 fifoE +makefifo fifo9 fifoA fifoF +makefifo fifoB fifoC fifoD +makefifo fifoE fifoF +makefifo fifo0 +makefifo +if [ -p fifo0 ]; then echo ok 0; fi +if [ -p fifo1 ]; then echo ok 1; fi +if [ -p fifo2 ]; then echo ok 2; fi +if [ -p fifo3 ]; then echo ok 3; fi +if [ -p fifo4 ]; then echo ok 4; fi +if [ -p fifo5 ]; then echo ok 5; fi +if [ -p fifo6 ]; then echo ok 6; fi +if [ -p fifo7 ]; then echo ok 7; fi +if [ -p fifo8 ]; then echo ok 8; fi +if [ -p fifo9 ]; then echo ok 9; fi +if [ -p fifoA ]; then echo ok A; fi +if [ -p fifoB ]; then echo ok B; fi +if [ -p fifoC ]; then echo ok C; fi +if [ -p fifoD ]; then echo ok D; fi +if [ -p fifoE ]; then echo ok E; fi +if [ -p fifoF ]; then echo ok F; fi +cd $TOP diff --git a/rts.tests/20-sleeper.exp b/rts.tests/20-sleeper.exp new file mode 100644 index 0000000..90c3f17 --- /dev/null +++ b/rts.tests/20-sleeper.exp @@ -0,0 +1,35 @@ +--- sleeper -w works +sleeper: warning: -w missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: fatal: unable to stat foo: file does not exist +ok +Caught CONT +Caught TERM + +--- sleeper -d works +sleeper: warning: -d missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: warning: -d invalid argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +ok +Caught CONT +Caught TERM + +--- sleeper -p works +sleeper: warning: -p missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: fatal: unable to stat foo: file does not exist +ok +Caught ALRM +Caught HUP +Caught CONT +Caught TERM + +--- sleeper -x works +sleeper: warning: -x missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: warning: -x invalid argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +ok +Caught CONT +Caught TERM diff --git a/rts.tests/20-sleeper.sh b/rts.tests/20-sleeper.sh new file mode 100644 index 0000000..76c821f --- /dev/null +++ b/rts.tests/20-sleeper.sh @@ -0,0 +1,63 @@ +echo '--- sleeper -w works' +sleeper -w +sleeper -w foo +makefifo sleeper.wait +catexe test.sv/run < test.sv/run chmod 755 test.sv/run touch test.sv/down diff --git a/rts.tests/supervise-base.sh b/rts.tests/supervise-base.sh index d7b55a1..c720aae 100644 --- a/rts.tests/supervise-base.sh +++ b/rts.tests/supervise-base.sh @@ -5,10 +5,17 @@ # svscanboot echo '--- supervise starts, svok works, svup works, svstat works, svc -x works' +rm -rf test.sv +mkdir test.sv +catexe test.sv/run < test.sv/run chmod 755 test.sv/run -( echo '#!/bin/sh'; echo echo second; echo svc -x . ) > test.sv/run2 +( echo '#!/bin/sh'; echo echo second; echo svc -x .; echo exit 100 ) > test.sv/run2 chmod 755 test.sv/run2 supervise test.sv & until svok test.sv do - sleep 1 + sleep 0 done svc -u test.sv wait diff --git a/rts.tests/supervise-downtime.sh b/rts.tests/supervise-downtime.sh index 8ca1695..2a04498 100644 --- a/rts.tests/supervise-downtime.sh +++ b/rts.tests/supervise-downtime.sh @@ -19,7 +19,7 @@ svpid=$! until svok test.sv do - sleep 1 + sleep 0 done svstat test.sv \ diff --git a/rts.tests/supervise-lock.sh b/rts.tests/supervise-lock.sh index c3d8bfc..f031d11 100644 --- a/rts.tests/supervise-lock.sh +++ b/rts.tests/supervise-lock.sh @@ -2,7 +2,7 @@ echo '--- supervise leaves locked service intact' supervise test.sv & until svok test.sv do - sleep 1 + sleep 0 done ( cd test.sv/supervise && ls -dl * | awk '{ print $1, $5, $9 }' ) supervise test.sv; echo $? diff --git a/rts.tests/supervise-start.sh b/rts.tests/supervise-start.sh index 83a7766..b15ebf3 100644 --- a/rts.tests/supervise-start.sh +++ b/rts.tests/supervise-start.sh @@ -1,7 +1,7 @@ echo '--- svc -o works first time with start' catexe test.sv/run < out +echo ok svc -dx . EOF catexe test.sv/start <test.sv/run -( echo '#!/bin/sh'; echo echo in stop ) >test.sv/stop +( echo '#!/bin/sh'; echo echo in stop; echo exit 100 ) >test.sv/stop rm -f test.sv/down chmod +x test.sv/run test.sv/stop supervise test.sv & @@ -11,7 +11,7 @@ echo echo '--- supervise stops log after main' ( echo '#!/bin/sh'; echo 'exec ../../sleeper' ) >test.sv/log chmod +x test.sv/log -supervise test.sv +supervise test.sv & wait rm -f test.sv/log echo diff --git a/rts.tests/svc-du.exp b/rts.tests/svc-du.exp new file mode 100644 index 0000000..21e5620 --- /dev/null +++ b/rts.tests/svc-du.exp @@ -0,0 +1,21 @@ +--- svc -du works, service exits 0 +ok +Caught CONT +Caught TERM +ok +ok + +--- svc -du works, service exits 1 +ok +Caught CONT +Caught TERM +ok +ok + +--- svc -du works, service exits 100 +ok +Caught CONT +Caught TERM +ok +ok + diff --git a/rts.tests/svc-du.sh b/rts.tests/svc-du.sh new file mode 100644 index 0000000..9af61a0 --- /dev/null +++ b/rts.tests/svc-du.sh @@ -0,0 +1,97 @@ +svpid() { + svstat test.sv \ + | sed -E -n 's/.+pid ([0-9][0-9]*).+/Z\1/; s/^[^Z].+/Z0/; s/Z//p' +} + +echo '--- svc -du works, service exits 0' +makefifo sv.wait1 sv.wait2 +catexe test.sv/run < test.sv/run -chmod 755 test.sv/run +makefifo fifo.out fifo.wait +catexe test.sv/run < svscan.pid +wait +EOF + +## this doesnt work. get the pid in svscanboot instead. +#catexe readproctitle <<'EOF' || die "Could not create readproctitle wrapper" +##!/bin/sh +#exec >readproctitle.log +#exec 2>&1 +#PATH=`echo $PATH | cut -d':' -f2-` +#exec env - PATH=$PATH readproctitle $@ & +#echo $! > test.boot/readproctitle.pid +#EOF + +sed -r \ + -e 's,PATH=/,PATH=.:..:../..:../../..:/,' \ + -e 's,^exec 2?>.+,,' \ + -e 's,/command/svc -dx .+,,g' \ + -e 's,/?service,service,g' \ + -e 's,readproctitle..*,& \& \ +,' \ + -e '$a\ +echo $! > readproctitle.pid' \ + -e '$a\ +wait' \ +< ../../svscanboot \ +| catexe svscanboot + +makefifo svc0.ready +catexe svc0/run <<'EOF' +#!/bin/sh +echo svc0 ran >> ../svc0.log +exec ../../../sleeper -w ../svc0.ready >> ../svc0.log +EOF + +makefifo svc1-main.ready +catexe svc1/run <<'EOF' +#!/bin/sh +echo svc1-main ran >> ../svc1-main.log +exec ../../../sleeper -w ../svc1-main.ready >> ../svc1-main.log +EOF + +makefifo svc1-log.ready +catexe svc1/log/run <<'EOF' +#!/bin/sh +echo svc1-log ran >> ../../svc1-log.log +exec ../../../../sleeper -w ../../svc1-log.ready >> ../../svc1-log.log +EOF + +makefifo svc2-main.ready +catexe svc2/run <<'EOF' +#!/bin/sh +echo svc2-main ran >> ../svc2-main.log +exec ../../../sleeper -w ../svc2-main.ready >> ../svc2-main.log +EOF + +makefifo svc2-log.ready +catexe svc2/log <<'EOF' +#!/bin/sh +echo svc2-log ran >> ../svc2-log.log +exec ../../../sleeper -w ../svc2-log.ready >> ../svc2-log.log +EOF + + +echo '--- svscanboot started' +./svscanboot > svscanboot.log 2>&1 & +svscanbootpid=$! +if [ "$svscanbootpid" != "0" ]; then + echo ok +fi +echo + +echo '--- svscan started' +svscanpid=`head -n 1 svscan.pid` +if [ "$svscanpid" != "0" ]; then + echo ok +fi +echo + +echo '--- readproctitle started' +readproctitlepid=`head -n 1 readproctitle.pid` +if [ "$readproctitlepid" != "0" ]; then + echo ok +fi +echo + + +check_pid_sanity() { + if [ `echo $1 | grep -E '^[1-9][0-9]{0,4}$' | wc -l` != "1" ] \ + || [ $1 -le 1 ] \ + || [ $1 -ge 99999 ] + then + echo pid = $1 >&2 + echo 0 + else + echo $1 + fi +} + +echo '--- svscanboot pid looks sane' +svscanbootpid=`check_pid_sanity $svscanbootpid` +if [ "$svscanbootpid" != "0" ]; then + echo ok +else + echo pid = $svscanbootpid +fi +echo + +echo '--- svscan pid looks sane' +svscanpid=`check_pid_sanity $svscanpid` +if [ "$svscanpid" != "0" ]; then + echo ok +else + echo pid = $svscanpid +fi +echo + +echo '--- readproctitle pid looks sane' +readproctitlepid=`check_pid_sanity $readproctitlepid` +if [ "$readproctitlepid" != "0" ]; then + echo ok +else + echo pid = $readprocpid +fi +echo + + +echo '--- svscanboot is running' +if kill -0 $svscanbootpid; then + echo ok +else + svscanbootpid=0 +fi +echo + +echo '--- svscan is running' +if kill -0 $svscanpid; then + echo ok +else + svscanpid=0 +fi +echo + +echo '--- readproctitle is running' +if kill -0 $readproctitlepid; then + echo ok +else + readproctitlepid=0 +fi +echo + + +echo '--- svc0.log ready' +cat svc0.ready +echo + +echo '--- svc1-main.log ready' +cat svc1-main.ready +echo + +echo '--- svc1-log.log ready' +cat svc1-log.ready +echo + +echo '--- svc2-main.log ready' +cat svc2-main.ready +echo + +echo '--- svc2-log.log ready' +cat svc2-log.ready +echo + + +echo '--- sigterm sent' +if [ "$svscanpid" != "0" ] && kill -TERM $svscanpid; then + echo ok +fi +echo + + +timed_stop() { + if [ $1 -ne 0 ]; then + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if kill -0 $1 2>/dev/null; then + if [ $i -eq 0 ]; then + kill -HUP $1 + break + fi + sleep $2 + else + echo ok + break + fi + done + fi +} + +echo '--- svscan is stopped' +timed_stop $svscanpid 1 +echo + +echo '--- readproctitle is stopped' +timed_stop $readproctitlepid 0 +echo + +echo '--- svscanboot is stopped' +timed_stop $svscanbootpid 0 +echo + + +timed_down() { + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if svok $1; then + svc -dx $1 + if [ $i -eq 0 ]; then + break + fi + sleep 1 + else + echo ok + break + fi + done +} + +echo '--- supervise svc0 is down' +timed_down svc0 +echo + +echo '--- supervise svc1 is down' +timed_down svc1 +echo + +echo '--- supervise svc1/log is down' +timed_down svc1/log +echo + +echo '--- supervise svc2 is down' +timed_down svc2 +echo + + +echo '--- svscanboot log' +cat svscanboot.log +echo + +echo '--- svc0 log' +cat svc0.log +echo + +echo '--- svc1 main log' +cat svc1-main.log +echo + +echo '--- svc1 log log' +cat svc1-log.log +echo + +echo '--- svc2 main log' +cat svc2-main.log | uniq +echo + +echo '--- svc2 log log' +cat svc2-log.log + + +# just in case +svc -dx svc0 svc1 svc1/log svc2 2>/dev/null + +cd $TOP + diff --git a/rts.tests/svscan.exp b/rts.tests/svscan.exp index 7a0b6c3..8a16481 100644 --- a/rts.tests/svscan.exp +++ b/rts.tests/svscan.exp @@ -1,5 +1,10 @@ --- svscan setup --- svscan start +go1log +go2log +go0 +go1 +go2 --- svscan out ==> svc0/output <== svc0 ran diff --git a/rts.tests/svscan.sh b/rts.tests/svscan.sh index 95eae95..5b39176 100644 --- a/rts.tests/svscan.sh +++ b/rts.tests/svscan.sh @@ -1,29 +1,37 @@ echo '--- svscan setup' -# set up services mkdir service svc0 svc1 svc2 svc2/log +makefifo svc0.wait svc1.wait svc1log.wait svc2.wait svc2log.wait catexe svc0/run <> output +echo go0 > ../svc0.wait +exit 100 EOF catexe svc1/run < ../svc1.wait +exit 100 EOF catexe svc1/log < output +echo go1log > ../svc1log.wait +exec cat >> output EOF catexe svc2/run < ../svc2.wait +exit 100 EOF catexe svc2/log/run < ../../svc2log.wait exec cat > ../output EOF @@ -33,21 +41,23 @@ echo '--- svscan start' svscan `pwd`/service >svscan.log 2>&1 & svscanpid=$! -until svok svc0 && svok svc1 && svok svc2 && svok svc2/log -do - sleep 1 -done +cat svc1log.wait +cat svc2log.wait +cat svc0.wait +cat svc1.wait +cat svc2.wait -# stop svscan and clean up kill $svscanpid wait >/dev/null 2>&1 while svok svc0 || svok svc1 || svok svc2 || svok svc2/log do - sleep 1 + sleep 0 done + echo '--- svscan out' head -n 1 svc[0-9]/output cat svscan.log rm -r svc0 svc1 svc2 service +rm -f svc0.wait svc1.wait svc1log.wait svc2.wait svc2log.wait diff --git a/sleeper.c b/sleeper.c index 00fed2c..a72d85b 100644 --- a/sleeper.c +++ b/sleeper.c @@ -1,39 +1,159 @@ +/* Options: + -d delay + waits delay nanoseconds before exiting. + -p fifo + sends output through fifo instead of stdout. opens, writes, and + closes fifo for each message sent. for signals that require + delay (CONT and TERM), the fifo is only opened once. also does + not exit after every signal unless a CONT/TERM pair. + -w fifo + opens fifo for write after signal handler set but before + entering main loop and sends "ok\n". + -x code + exits with supplied code. +*/ +#include +#include +#include +#include #include #include "byte.h" +#include "error.h" +#include "iopause.h" +#include "ndelay.h" +#include "scan.h" #include "sig.h" #include "str.h" -#include +#include "stralloc.h" +#include "strerr.h" +#include "subgetopt.h" + +#define WARNING "sleeper: warning: " +#define FATAL "sleeper: fatal: " +#define USAGE "sleeper: usage: sleeper " + +static int selfpipe[2]; +static stralloc opt_p = {0,0,0}; +static stralloc opt_w = {0,0,0}; +static int opt_d = -1; +static int opt_x = 0; + +static void die_usage(void) +{ + strerr_die2x(100,USAGE,"[-d delay] [-p pfifo] [-w wfifo] [-x code]"); +} static void catch_sig(int sig) +{ + int ignored; + char c; + + c = (char)sig; + ignored = write(selfpipe[1],&c,1); + (void)ignored; +} + +static void show_sig(int sig, int fd) { char buf[7+14+2] = "Caught "; const char *name; int ignored; int i; + switch (sig) { - case SIGALRM: name = "ALRM"; break; - case SIGCONT: name = "CONT"; break; - case SIGHUP: name = "HUP"; break; - case SIGINT: name = "INT"; break; - case SIGQUIT: name = "QUIT"; break; - case SIGTERM: name = "TERM"; break; - case SIGUSR1: name = "USR1"; break; - case SIGUSR2: name = "USR2"; break; - case SIGWINCH: name = "WINCH"; break; - default: name = "unknown signal"; + case SIGALRM: name = "ALRM"; break; + case SIGCONT: name = "CONT"; break; + case SIGHUP: name = "HUP"; break; + case SIGINT: name = "INT"; break; + case SIGQUIT: name = "QUIT"; break; + case SIGTERM: name = "TERM"; break; + case SIGUSR1: name = "USR1"; break; + case SIGUSR2: name = "USR2"; break; + case SIGWINCH: name = "WINCH"; break; + default: name = "unknown signal"; } i = str_len(name); byte_copy(buf+7,i,name); i += 7; buf[i++] = '\n'; - ignored = write(1,buf,i); - if (sig != SIGCONT) - _exit(1); + ignored = write(fd,buf,i); (void)ignored; } -int main(void) +static int openp(void) +{ + struct stat st; + int fd; + if (opt_p.len) { + if (stat(opt_p.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_p.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_p.s); + while ((fd = open(opt_p.s,O_WRONLY|O_APPEND)) == -1) { + if (errno == error_intr) continue; + strerr_die4sys(111,FATAL,"open: ",opt_p.s,""); + } + } + else fd = 1; + return fd; +} + +static void closep(int fd) +{ + if (opt_p.len) close(fd); +} + +static void show_err(void) { + int ignored; + + ignored = write(1,"invalid signal\n",15); + return; + (void)ignored; +} + +static void show_one(int sig) +{ + int fd; + fd = openp(); + show_sig(sig,fd); + closep(fd); + return; +} + +static void show_two(int sig1, int sig2) +{ + int fd; + fd = openp(); + show_sig(sig1,fd); + show_sig(sig2,fd); + closep(fd); + return; +} + +int main(int argc, const char *const *argv) +{ + struct stat st; + struct taia deadline; + struct taia stamp; + iopause_fd pausefd; + unsigned long tmp; + int r; + int opt; + int nc = 0; + int nt = 0; + int oc = 0; + int ot = 0; + int new_sig = 0; + int old_sig = 0; + int ignored; + char buf; + char p[2]; + + if (pipe(selfpipe) == -1) + strerr_die1sys(111,"sleeper: fatal: unable to create pipe"); + ndelay_on(selfpipe[1]); + sig_catch(SIGALRM,catch_sig); sig_catch(SIGCONT,catch_sig); sig_catch(SIGHUP,catch_sig); @@ -43,6 +163,117 @@ int main(void) sig_catch(SIGUSR1,catch_sig); sig_catch(SIGUSR2,catch_sig); sig_catch(SIGWINCH,catch_sig); - sleep(9999); - return 0; + + while ((opt = sgopt(argc,argv,"d:p:w:x:")) != sgoptdone) + switch (opt) { + case 'd': + if (scan_ulong(sgoptarg,&tmp)) { + if (tmp >= 0) { + opt_d = (int)tmp; + continue; + } + } + strerr_warn2(WARNING,"-d invalid argument",0); + die_usage(); + case 'p': + stralloc_copys(&opt_p,sgoptarg); + stralloc_0(&opt_p); + continue; + case 'w': + stralloc_copys(&opt_w,sgoptarg); + stralloc_0(&opt_w); + continue; + case 'x': + if (scan_ulong(sgoptarg,&tmp)) { + if (tmp >= 0) { + opt_x = (int)tmp; + continue; + } + } + strerr_warn2(WARNING,"-x invalid argument",0); + die_usage(); + default: + p[0] = (char)sgoptproblem; + p[1] = '\0'; + if (argv[sgoptind] && (sgoptind < argc)) + strerr_warn3(WARNING,"illegal option -",p,0); + else + strerr_warn4(WARNING,"-",p," missing argument",0); + die_usage(); + } + argv += sgoptind; + + if (opt_p.len) { + if (stat(opt_p.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_p.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_p.s); + } + + if (opt_w.len) { + int fifofd; + if (stat(opt_w.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_w.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_w.s); + while ((fifofd = open(opt_w.s,O_WRONLY)) == -1) { + if (errno == error_intr) continue; + strerr_die4sys(111,FATAL,"open: ",opt_w.s,""); + } + ignored = write(fifofd,"ok\n",3); + close(fifofd); + } + + do { + for (;;) { + r = read(selfpipe[0],&buf,1); + if (!r) break; + if (r == -1) { + if (errno == error_intr) continue; + break; + } + + new_sig = (int)buf; + + nc = new_sig == SIGCONT; + nt = new_sig == SIGTERM; + oc = old_sig == SIGCONT; + ot = old_sig == SIGTERM; + + if (!nc && !nt && !oc && !ot) {show_one(new_sig); break; } + if (!nc && !nt && !oc && ot) {show_two(SIGTERM, new_sig); break; } + if (!nc && !nt && oc && !ot) {show_two(SIGCONT, new_sig); break; } + if (!nc && !nt && oc && ot) {show_err(); break; } + if (!nc && nt && !oc && !ot) {old_sig = SIGTERM; continue;} + if (!nc && nt && !oc && ot) {show_one(SIGTERM); continue;} + if (!nc && nt && oc && !ot) {show_two(SIGCONT, SIGTERM); break; } + if (!nc && nt && oc && ot) {show_err(); break; } + if ( nc && !nt && !oc && !ot) {old_sig = SIGCONT; continue;} + if ( nc && !nt && !oc && ot) {show_two(SIGCONT, SIGTERM); break; } + if ( nc && !nt && oc && !ot) {show_one(SIGCONT); continue;} + if ( nc && !nt && oc && ot) {show_err(); break; } + if ( nc && nt && !oc && !ot) {show_err(); break; } + if ( nc && nt && !oc && ot) {show_err(); break; } + if ( nc && nt && oc && !ot) {show_err(); break; } + if ( nc && nt && oc && ot) {show_err(); break; } + } + old_sig = 0; + if ((oc && nt) || (ot && nc)) break; + } while (opt_p.len); + + if (opt_d >= 0) { + deadline.sec.x = 0; + deadline.nano = opt_d; + deadline.atto = 0; + taia_now(&stamp); + taia_add(&deadline,&deadline,&stamp); + for (;;) { + taia_now(&stamp); + if (taia_less(&deadline,&stamp)) break; + iopause(&pausefd,0,&deadline,&stamp); + } + } + + _exit(opt_x); + (void)ignored; } diff --git a/sleeper=x b/sleeper=x index 4455370..5be7a03 100644 --- a/sleeper=x +++ b/sleeper=x @@ -1,2 +1,3 @@ +time.a byte.a unix.a diff --git a/softlimit.c b/softlimit.c index ea4c5b0..2e17de7 100644 --- a/softlimit.c +++ b/softlimit.c @@ -99,7 +99,7 @@ int main(int argc,const char *const *argv,const char *const *envp) while ((opt = getopt(argc,argv,"a:c:d:f:l:m:o:p:r:s:t:")) != opteof) switch(opt) { case '?': - die_usage(); + die_usage(); case 'a': #ifdef RLIMIT_AS doit(RLIMIT_AS,optarg); @@ -144,7 +144,7 @@ int main(int argc,const char *const *argv,const char *const *envp) #ifdef RLIMIT_AS doit(RLIMIT_AS,optarg); #endif - break; + break; case 'o': #ifdef RLIMIT_NOFILE doit(RLIMIT_NOFILE,optarg); diff --git a/subgetopt.c b/subgetopt.c index 266e72a..85ace96 100644 --- a/subgetopt.c +++ b/subgetopt.c @@ -54,7 +54,7 @@ int sgopt(int argc,const char *const *argv,const char *opts) optproblem = c; return '?'; } - ++optind; + ++optind; } } return c; diff --git a/supervise.c b/supervise.c index 201ab09..be57eef 100644 --- a/supervise.c +++ b/supervise.c @@ -33,6 +33,8 @@ struct svc int flagpaused; struct taia when; int ranstop; + struct taia after; + struct taia stopafter; }; const char *dir; @@ -50,6 +52,7 @@ const char *runscript = 0; int logpipe[2] = {-1,-1}; struct svc svcmain = {0,svstatus_stopped,1,1}; struct svc svclog = {0,svstatus_stopped,1,0}; +struct taia half; static int stat_isexec(const char *path) { @@ -121,11 +124,11 @@ static int forkexecve(struct svc *svc,const char *argv[],int fd) sig_uncatch(sig_ttystop); sig_uncatch(sig_cont); if (stat_exists("no-setsid") == 0) - setsid(); /* shouldn't fail; if it does, too bad */ + setsid(); /* shouldn't fail; if it does, too bad */ if (fd >= 0 && logpipe[0] >= 0) { - dup2(logpipe[fd],fd); - close(logpipe[0]); - close(logpipe[1]); + dup2(logpipe[fd],fd); + close(logpipe[0]); + close(logpipe[1]); } execve(argv[0],(char*const*)argv,environ); strerr_die4sys(111,FATAL,"unable to start ",dir,argv[0]+1); @@ -209,6 +212,7 @@ void trystart(struct svc *svc) const char *argv[] = { 0,0 }; int f; int fd; + struct taia now; if (svc == &svclog) { argv[0] = "./log"; @@ -228,16 +232,22 @@ void trystart(struct svc *svc) svcmain.flagstatus = firstrun ? svstatus_starting : svstatus_running; fd = 1; } + taia_now(&now); + iopause(0,0,&svc->after,&now); if ((f = forkexecve(svc,argv,fd)) < 0) return; pidchange(svc,"start",0,f); - deepsleep(1); + taia_now(&now); + taia_add(&svc->after,&half,&now); + if (svc == &svclog) + svcmain.after = svclog.after; } void trystop(struct svc *svc) { const char *argv[] = { "./stop",0 }; int f; + struct taia now; if (svc->ranstop || svc != &svcmain @@ -247,21 +257,34 @@ void trystop(struct svc *svc) announce(); return; } + taia_now(&now); + iopause(0,0,&svc->stopafter,&now); runscript = argv[0]; if ((f = forkexecve(svc,argv,1)) < 0) return; svc->ranstop = 1; pidchange(svc,"start",0,f); - deepsleep(1); + taia_now(&now); + taia_add(&svc->stopafter,&half,&now); + if (svc == &svclog) + svcmain.stopafter = svclog.stopafter; } static void stopsvc(int killpid,struct svc *svc) { + struct taia now; + + taia_now(&now); + iopause(0,0,&svc->stopafter,&now); kill(killpid,SIGTERM); kill(killpid,SIGCONT); svc->flagpaused = 0; svc->flagstatus = svstatus_stopping; svc->ranstop = 0; + taia_now(&now); + taia_add(&svc->stopafter,&half,&now); + if (svc == &svclog) + svcmain.stopafter = svclog.stopafter; } void doit(void) @@ -301,123 +324,133 @@ void doit(void) if (!r) break; if ((r == -1) && (errno != error_intr)) break; if (r == svcmain.pid) - svc = &svcmain; + svc = &svcmain; else if (r == svclog.pid) - svc = &svclog; + svc = &svclog; else - continue; + continue; killpid = svc->pid; svc->pid = 0; - if (((svc == &svcmain && svc->flagstatus == svstatus_starting) && (wait_crashed(wstat) || wait_exitcode(wstat) != 0)) - || (!wait_crashed(wstat) && wait_exitcode(wstat) == 100)) { - svc->flagwantup = 0; - svc->flagstatus = svstatus_failed; + if ((svc == &svcmain && svc->flagstatus == svstatus_starting) && (wait_crashed(wstat) || wait_exitcode(wstat) != 0)) { + svc->flagwantup = 0; + svc->flagstatus = svstatus_failed; + } + else if (!wait_crashed(wstat) && wait_exitcode(wstat) == 100) { + if (svc->flagwantup) { + svc->flagstatus = svstatus_starting; + taia_now(&svc->after); + } + else { + svc->flagstatus = svstatus_failed; + } } else if (svc == &svcmain && svc->flagstatus == svstatus_starting) { } - else if (!svc->flagwant || !svc->flagwantup) - svc->flagstatus = svstatus_stopped; + else if (!svc->flagwant || !svc->flagwantup) { + svc->flagstatus = svstatus_stopped; + } pidchange(svc, wait_crashed(wstat) ? "killed" : "exit", - wait_crashed(wstat) ? wait_stopsig(wstat) : wait_exitcode(wstat), - killpid); + wait_crashed(wstat) ? wait_stopsig(wstat) : wait_exitcode(wstat), + killpid); firstrun = 0; if ((svc->flagwant && svc->flagwantup) || (svc == &svcmain && svc->flagstatus == svstatus_starting)) { - if (!flagexit) - trystart(svc); + if (!flagexit) + trystart(svc); } else if (svc->flagstatus != svstatus_failed) - trystop(svc); + trystop(svc); break; } svc = &svcmain; killpid = svc->pid; - while (read(fdcontrol,&ch,1) == 1) + while (read(fdcontrol,&ch,1) == 1) { switch(ch) { case '+': - if (killpid > 0) killpid = -killpid; - break; + if (killpid > 0) killpid = -killpid; + break; case '=': - if (killpid < 0) killpid = -killpid; - break; + if (killpid < 0) killpid = -killpid; + break; case 'L': - svc = &svclog; - killpid = svc->pid; - break; + svc = &svclog; + killpid = svc->pid; + break; case 'l': - svc = &svcmain; - killpid = svc->pid; - break; - case 'd': - svc->flagwant = 1; - svc->flagwantup = 0; - if (killpid) - stopsvc(killpid,svc); - else - trystop(svc); - announce(); - break; - case 'u': - if (svc == &svcmain) - firstrun = !svcmain.flagwantup; - svc->flagwant = 1; - svc->flagwantup = 1; - if (!svc->pid) - svc->flagstatus = svstatus_starting; - announce(); - if (!svc->pid) trystart(svc); - break; - case 'o': - svc->flagwant = 0; - announce(); - if (!svc->pid) trystart(svc); - break; - case 'a': - if (killpid) kill(killpid,SIGALRM); - break; - case 'h': - if (killpid) kill(killpid,SIGHUP); - break; - case 'k': - if (killpid) kill(killpid,SIGKILL); - break; - case 't': - if (killpid) kill(killpid,SIGTERM); - break; - case 'i': - if (killpid) kill(killpid,SIGINT); - break; - case 'q': - if (killpid) kill(killpid,SIGQUIT); - break; - case '1': - if (killpid) kill(killpid,SIGUSR1); - break; - case '2': - if (killpid) kill(killpid,SIGUSR2); - break; - case 'w': - if (killpid) kill(killpid,SIGWINCH); - break; - case 'p': - svc->flagpaused = 1; - announce(); - if (killpid) kill(killpid,SIGSTOP); - break; - case 'c': - svc->flagpaused = 0; - announce(); - if (killpid) kill(killpid,SIGCONT); - break; - case 'x': - flagexit = 1; - announce(); - break; + svc = &svcmain; + killpid = svc->pid; + break; + case 'd': + svc->flagwant = 1; + svc->flagwantup = 0; + if (killpid) + stopsvc(killpid,svc); + else + trystop(svc); + announce(); + break; + case 'u': + if (svc == &svcmain) + firstrun = !svcmain.flagwantup; + svc->flagwant = 1; + svc->flagwantup = 1; + if (!svc->pid) + svc->flagstatus = svstatus_starting; + announce(); + if (!svc->pid) trystart(svc); + break; + case 'o': + svc->flagwant = 0; + announce(); + if (!svc->pid) trystart(svc); + break; + case 'a': + if (killpid) kill(killpid,SIGALRM); + break; + case 'h': + if (killpid) kill(killpid,SIGHUP); + break; + case 'k': + if (killpid) kill(killpid,SIGKILL); + break; + case 't': + if (killpid) kill(killpid,SIGTERM); + break; + case 'i': + if (killpid) kill(killpid,SIGINT); + break; + case 'q': + if (killpid) kill(killpid,SIGQUIT); + break; + case '1': + if (killpid) kill(killpid,SIGUSR1); + break; + case '2': + if (killpid) kill(killpid,SIGUSR2); + break; + case 'w': + if (killpid) kill(killpid,SIGWINCH); + break; + case 'p': + svc->flagpaused = 1; + announce(); + if (killpid) kill(killpid,SIGSTOP); + break; + case 'c': + svc->flagpaused = 0; + announce(); + if (killpid) kill(killpid,SIGCONT); + break; + case 'x': + flagexit = 1; + announce(); + break; } + } if (flagexit - && svcmain.flagstatus == svstatus_stopped - && (svclog.flagstatus == svstatus_running || svclog.flagstatus == svstatus_started)) + && svcmain.flagstatus == svstatus_stopped + && (svclog.flagstatus == svstatus_running || svclog.flagstatus == svstatus_started)) stopsvc(svclog.pid,&svclog); } } @@ -501,6 +534,15 @@ int main(int argc,char **argv) strerr_die3sys(111,FATAL,"unable to read ",fntemp); closeonexec(fdok); + taia_now(&svclog.after); + svcmain.after = svclog.after; + svclog.stopafter = svclog.after; + svcmain.stopafter = svclog.stopafter; + + half.sec.x = 0; + half.nano = 500000000; + half.atto = 0; + if (!svclog.flagwant || svclog.flagwantup) trystart(&svclog); if (!svcmain.flagwant || svcmain.flagwantup) trystart(&svcmain); diff --git a/svc.c b/svc.c index 79e9397..0063f4e 100644 --- a/svc.c +++ b/svc.c @@ -50,8 +50,7 @@ int main(int argc,const char *const *argv) while ((dir = *argv++) != 0) { if (chdir(dir) == -1) strerr_warn4sys(WARNING,"unable to chdir to ",dir,""); - else if (!svpath_init() - || (fncontrol = svpath_make("/control")) == 0) + else if (!svpath_init() || (fncontrol = svpath_make("/control")) == 0) strerr_warn4sys(WARNING,"unable to setup control path for ",dir,""); else { fd = open_write(fncontrol); diff --git a/svpath.c b/svpath.c index 114d935..631b508 100644 --- a/svpath.c +++ b/svpath.c @@ -19,7 +19,7 @@ int svpath_init(void) return 0; for (ptr = cwd+1; *ptr != 0; ++ptr) if (*ptr == '/') - *ptr = ':'; + *ptr = ':'; if (!stralloc_cats(&svdir, cwd)) return 0; } diff --git a/svscan.c b/svscan.c index edcc46b..70f99b4 100644 --- a/svscan.c +++ b/svscan.c @@ -65,7 +65,7 @@ void start(const char *fn) for (i = 0;i < numx;++i) if (x[i].ino == st.st_ino) if (x[i].dev == st.st_dev) - break; + break; if (i == numx) { if (numx >= SERVICES) { @@ -83,12 +83,12 @@ void start(const char *fn) byte_copy(fnlog,fnlen,fn); byte_copy(fnlog + fnlen,5,"/log"); if (stat(fnlog,&st) == 0) - x[i].flaglog = S_ISDIR(st.st_mode); + x[i].flaglog = S_ISDIR(st.st_mode); else - if (errno != error_noent) { + if (errno != error_noent) { strerr_warn4sys(WARNING,"unable to stat ",fn,"/log"); return; - } + } } if (x[i].flaglog) { @@ -111,18 +111,18 @@ void start(const char *fn) return; case 0: if (x[i].flaglog) - if (fd_move(1,x[i].pi[1]) == -1) + if (fd_move(1,x[i].pi[1]) == -1) + strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); + if (i == logx) + if (fd_move(0,logpipe[0]) == -1) strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); - if (i == logx) - if (fd_move(0,logpipe[0]) == -1) - strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); args[0] = "supervise"; args[1] = fn; args[2] = 0; - pathexec_run(*args,args,(const char*const*)environ); + pathexec_run(*args,args,(const char*const*)environ); strerr_die3sys(111,WARNING,"unable to start supervise ",fn); default: - x[i].pid = child; + x[i].pid = child; all_stopped = 0; } else @@ -140,15 +140,15 @@ void start(const char *fn) case 0: if (fd_move(0,x[i].pi[0]) == -1) strerr_die4sys(111,WARNING,"unable to set up descriptors for ",fn,"/log"); - if (chdir(fn) == -1) + if (chdir(fn) == -1) strerr_die3sys(111,WARNING,"unable to switch to ",fn); args[0] = "supervise"; args[1] = "log"; args[2] = 0; - pathexec_run(*args,args,(const char*const*)environ); + pathexec_run(*args,args,(const char*const*)environ); strerr_die4sys(111,WARNING,"unable to start supervise ",fn,"/log"); default: - x[i].pidlog = child; + x[i].pidlog = child; all_stopped = 0; } else diff --git a/svstat.c b/svstat.c index c2a91b0..f010b7a 100644 --- a/svstat.c +++ b/svstat.c @@ -173,8 +173,8 @@ void doit(const char *dir) if (check_log != 0) { if (r >= 20+18) { if (check_log < 0) { - buffer_puts(&b,"\n"); - buffer_puts(&b,dir); + buffer_puts(&b,"\n"); + buffer_puts(&b,dir); } buffer_puts(&b," log: "); showstatus(status+20,r-20,normallyup); diff --git a/svup.c b/svup.c index 6a78b66..76de1eb 100644 --- a/svup.c +++ b/svup.c @@ -13,7 +13,7 @@ static int checkstatus(const char status[19], int r) /* Check for a PID */ return (status[12] || status[13] || status[14] || status[15]) /* Check for a PID */ || (r > 18 - && (status[18] == svstatus_started || status[18] == svstatus_running)); + && (status[18] == svstatus_started || status[18] == svstatus_running)); } static void die_usage(void) @@ -82,11 +82,11 @@ int main(int argc,const char *const *argv) if (check_log != 0) { if (rd < 20+18) { if (check_log > 0) - _exit(100); + _exit(100); } else if (!checkstatus(status+20,rd-20)) - _exit(100); + _exit(100); } _exit(0); }