commit 34ead97e601c33575186a62c2eb41be9aee8190d
parent f2331438f8baa51d4b31b15b345ec71887e36968
Author: Gerrit Pape <pape@smarden.org>
Date:   Thu, 24 Apr 2003 11:12:46 +0000
  * runsvdir.c: don't propagate sig_term to runsv processes when receiving
    sig_term; send sig_term to all runsv processes and exit 111 when
    receiving sig_hangup.
  * svlogd.c: code cleanup.
  * svwaitdown.c: send command "d" (and "x" if -x is set) to a service if
    it's not in state 'want down'.
  * svwaitup.c: minor code cleanup.
  * man/runsvdir.8, man/svwaitdown.8: adapt.
0.9.0.
Diffstat:
23 files changed, 237 insertions(+), 123 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
 DESTDIR=
 
-PACKAGE=runit-0.8.4
+PACKAGE=runit-0.9.0
 DIRS=doc man etc package src
 MANPAGES=runit.8 runit-init.8 runsvdir.8 runsv.8 svwaitdown.8 svwaitup.8 \
 utmpset.8 runsvchdir.8 runsvstat.8 runsvctrl.8 svlogd.8
diff --git a/debian/changelog b/debian/changelog
@@ -1,3 +1,9 @@
+runit (0.9.0-1) unstable; urgency=low
+
+  * new upstream version.
+
+ -- Gerrit Pape <pape@smarden.org>  Thu, 24 Apr 2003 13:11:57 +0200
+
 runit (0.8.4-1) unstable; urgency=low
 
   * new upstream version.
diff --git a/debian/rules b/debian/rules
@@ -26,11 +26,11 @@ build-arch-stamp:
 	# Add here command to compile/build the package.
 	#	$(MAKE)
 
-	tar xfzvp runit-0.8.4.tar.gz
+	tar xfzvp runit-0.9.0.tar.gz
 	( \
 	set -e; \
-	cd admin/runit-0.8.4/src; \
-	ln -s runit-0.8.4 runit; mv runit ../..; \
+	cd admin/runit-0.9.0/src; \
+	ln -s runit-0.9.0 runit; mv runit ../..; \
 	echo 'diet -v -Os gcc -O2 -Wall' >conf-cc; \
 	echo 'diet -v -Os gcc -s -Os -pipe' >conf-ld; \
 	$(MAKE); \
@@ -74,28 +74,28 @@ install: build
 	#	$(MAKE) install DESTDIR=$(CURDIR)/debian/runit
 
 	# runit
-	install -m0500 admin/runit-0.8.4/src/runit \
+	install -m0500 admin/runit-0.9.0/src/runit \
 	  $(CURDIR)/debian/runit/sbin/runit
-	install -m0500 admin/runit-0.8.4/src/runit-init \
+	install -m0500 admin/runit-0.9.0/src/runit-init \
 	  $(CURDIR)/debian/runit/sbin/runit-init
-	install -m0755 admin/runit-0.8.4/src/runsvdir \
+	install -m0755 admin/runit-0.9.0/src/runsvdir \
 	  $(CURDIR)/debian/runit/usr/bin/runsvdir
-	install -m0755 admin/runit-0.8.4/src/runsv \
+	install -m0755 admin/runit-0.9.0/src/runsv \
 	  $(CURDIR)/debian/runit/usr/bin/runsv
-	install -m0755 admin/runit-0.8.4/src/runsvchdir \
+	install -m0755 admin/runit-0.9.0/src/runsvchdir \
 	  $(CURDIR)/debian/runit/usr/sbin/runsvchdir
-	install -m0755 admin/runit-0.8.4/src/svlogd \
+	install -m0755 admin/runit-0.9.0/src/svlogd \
 	  $(CURDIR)/debian/runit/usr/bin/svlogd
-	install -m0755 admin/runit-0.8.4/src/svwaitdown \
+	install -m0755 admin/runit-0.9.0/src/svwaitdown \
 	  $(CURDIR)/debian/runit/usr/bin/svwaitdown
-	install -m0755 admin/runit-0.8.4/src/svwaitup \
+	install -m0755 admin/runit-0.9.0/src/svwaitup \
 	  $(CURDIR)/debian/runit/usr/bin/svwaitup
-	install -m0755 admin/runit-0.8.4/src/utmpset \
+	install -m0755 admin/runit-0.9.0/src/utmpset \
 	  $(CURDIR)/debian/runit/usr/sbin/utmpset
 
-	install -m0755 admin/runit-0.8.4/src/runsvstat \
+	install -m0755 admin/runit-0.9.0/src/runsvstat \
 	  $(CURDIR)/debian/runit/usr/bin/runsvstat
-	install -m0755 admin/runit-0.8.4/src/runsvctrl \
+	install -m0755 admin/runit-0.9.0/src/runsvctrl \
 	  $(CURDIR)/debian/runit/usr/bin/runsvctrl
 
 #	install -m0700 debian/1 \
@@ -148,7 +148,7 @@ binary-arch: build install
 #	dh_installexamples -a
 	dh_installman -a admin/runit/man/*.8
 #	dh_undocumented -a
-	dh_installchangelogs -a admin/runit-0.8.4/package/CHANGES
+	dh_installchangelogs -a admin/runit-0.9.0/package/CHANGES
 	dh_strip -a
 #	dh_link -a
 	dh_compress -a
diff --git a/doc/install.html b/doc/install.html
@@ -13,14 +13,14 @@ Check that you have the recent version of
 <a href="http://cr.yp.to/daemontools.html">daemontools</a> installed.
 <p>
 Download
-<a href="runit-0.8.4.tar.gz">runit-0.8.4.tar.gz</a> into <tt>/package</tt>
+<a href="runit-0.9.0.tar.gz">runit-0.9.0.tar.gz</a> into <tt>/package</tt>
 and unpack the archive
 <pre>
   # cd /package
-  # gunzip runit-0.8.4.tar
-  # tar -xpf runit-0.8.4.tar
-  # rm runit-0.8.4.tar
-  # cd admin/runit-0.8.4
+  # gunzip runit-0.9.0.tar
+  # tar -xpf runit-0.9.0.tar
+  # rm runit-0.9.0.tar
+  # cd admin/runit-0.9.0
 </pre>
 Compile and install the <i>runit</i> programs
 <pre>
diff --git a/doc/replaceinit.html b/doc/replaceinit.html
@@ -107,7 +107,7 @@ default Unix process no 1 <i>runit</i>.
 </pre>
 To report success:
 <pre>
-  # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.8.4@smarden.org
+  # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.9.0@smarden.org
 </pre>
 <hr>
 
@@ -188,7 +188,7 @@ Use <b>init 6</b> to reboot and <b>init 0</b> to halt a system that runs
 <p>
 To report success:
 <pre>
-  # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.8.4@smarden.org
+  # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.9.0@smarden.org
 </pre>
 <h3>Step 5: Service migration</h3>
 The goal is to migrate all services from <i>/etc/rc.*</i> scheme to the
diff --git a/man/runit-init.8 b/man/runit-init.8
@@ -47,8 +47,12 @@ and
 returns 111 on error, 0 in all other cases.
 .SH SEE ALSO
 runit(8),
-svwaitdown(8),
-svwaitup(8),
+runsv(8),
+runsvctrl(8),
+runsvstat(8),
+runsvdir(8),
+runsvchdir(8),
+svlogd(8),
 utmpset(8)
 .P
 http://smarden.org/runit/
diff --git a/man/runit.8 b/man/runit.8
@@ -73,9 +73,13 @@ receives an INT signal, a ctrl-alt-del keyboard request is triggered.
 .SH SEE ALSO
 runit-init(8),
 runsvdir(8),
+runsvchdir(8),
 runsv(8),
+runsvctrl(8),
+runsvstat(8),
 svwaitdown(8),
 svwaitup(8),
+svlogd(8),
 utmpset(8)
 .P
 http://smarden.org/runit/
diff --git a/man/runsv.8 b/man/runsv.8
@@ -153,9 +153,15 @@ is running in
 .B runsv
 exits 0 if it was told to exit.
 .SH SEE ALSO
+runsvctrl(8),
+runsvstat(8),
 runit(8),
 runit-init(8),
 runsvdir(8),
+runsvchdir(8),
+svlogd(8),
+svwaitdown(8),
+svwaitup(8),
 svc(8),
 supervise(8)
 .P
diff --git a/man/runsvchdir.8 b/man/runsvchdir.8
@@ -46,8 +46,12 @@ exits 0 on success.
 .SH SEE ALSO
 runsvdir(8),
 runsv(8),
+runsvctrl(8),
+runsvstat(8),
 runit(8),
-runit-init(8)
+runit-init(8),
+svwaitdown(8),
+svwaitup(8)
 .P
 http://smarden.org/runit/
 .SH AUTHOR
diff --git a/man/runsvctrl.8 b/man/runsvctrl.8
@@ -96,10 +96,12 @@ increases the exit code by one and exits non zero. The maximum is 100.
 exits 111 on error.
 .SH SEE ALSO
 runsvstat(8),
+runsv(8),
 runit(8),
 runit-init(8),
 runsvdir(8),
-runsv(8),
+runsvchdir(8),
+svlogd(8),
 svwaitdown(8),
 svwaitup(8)
 .P
diff --git a/man/runsvdir.8 b/man/runsvdir.8
@@ -73,13 +73,23 @@ in stage 2.
 .SH SIGNALS
 If
 .B runsvdir
-receives a TERM signal, it sends a TERM signal to each
+receives a TERM signal, it exits with 0 immediately.
+.P
+If
+.B runsvdir
+receives a HUP signal, it sends a TERM signal to each
 .BR runsv (8)
-process it is monitoring and then exits with 0.
+process it is monitoring and then exits with 111.
 .SH SEE ALSO
+runsvchdir(8),
+runsv(8),
+runsvctrl(8),
+runsvstat(8),
 runit(8),
 runit-init(8),
-runsv(8),
+svlogd(8),
+svwaitdown(8),
+svwaitup(8),
 readproctitle(8),
 svscan(8)
 .P
diff --git a/man/runsvstat.8 b/man/runsvstat.8
@@ -54,10 +54,12 @@ increases the exit code by one and exits non zero. The maximum is 100.
 exits 111 on error.
 .SH SEE ALSO
 runsvctrl(8),
+runsv(8),
+runsvdir(8),
+runsvchdir(8),
 runit(8),
 runit-init(8),
-runsvdir(8),
-runsv(8),
+svlogd(8),
 svwaitdown(8),
 svwaitup(8)
 .P
diff --git a/man/svlogd.8 b/man/svlogd.8
@@ -158,6 +158,15 @@ should rotate the current log file to
 .I size
 bytes.
 Default is 1000000.
+If
+.I size
+is zero,
+.B svlogd
+doesn't rotate log files.
+You should set
+.I size
+to at least (2 *
+.IR len ).
 .TP
 .RI n num
 sets the maximum number of old log files
@@ -213,6 +222,26 @@ are printed to standard error.
 Initially each line is selected.
 Deselected log messages are discarded from
 .IR log .
+.SH PATTERN MATCHING
+.B svlogd
+matches a log message against the string
+.I pattern
+as follows:
+.P
+.I pattern
+is applied to the log message one character by one, starting with the first.
+A character not a star (``*'') and not a plus (``+'') matches itself.
+A plus matches the next character in
+.I pattern
+in the log message one or more times.
+A star before the end of
+.I pattern
+matches any string in the log message that does not include the next
+character in
+.IR pattern .
+A star at the end of
+.I pattern
+matches any string.
 .SH OPTIONS
 .TP
 .B \-t
@@ -229,10 +258,10 @@ replace.
 must be a single character.
 Replace non-printable characters in log messages with
 .IR c .
-Character are replaced before pattern matching is applied.
+Characters are replaced before pattern matching is applied.
 .TP
 .B \-R \fIabc
-replace characters.
+replace charset.
 Additionally to non-printable characters, replace all characters found in
 .I abc
 with
@@ -268,27 +297,27 @@ and updates their configuration according to
 .P
 If
 .B svlogd
-is sent a TERM signal, or if it sees end-of-file on standard input, it
-closes standard input, waits for all
+is sent a TERM signal, or if it sees end-of-file on standard input, it stops
+reading standard input, processes the data in the buffer, waits for all
 .I processor
 subprocesses to finish if any, and exits 0 as soon as possible.
 .P
 If
 .B svlogd
-is sent an ALRM signal, it tries for all
+is sent an ALRM signal, it forces log file rotation for all
 .I logs
-to rotate the current log file, if it is not empty.
+with a non empty
+.I current
+log file.
 .SH SEE ALSO
-runsvstat(8),
-runit(8),
-runit-init(8),
 runsv(8),
 runsvstat(8),
 runsvctrl(8),
 runsvdir(8),
 runsvchdir(8),
-svwaitdown(8),
-svwaitup(8)
+runit(8),
+runit-init(8),
+multilog(8)
 .P
 http://smarden.org/runit/
 .SH AUTHOR
diff --git a/man/svwaitdown.8 b/man/svwaitdown.8
@@ -14,14 +14,15 @@ svwaitdown \- waits for services controlled by supervise(8) to be down
 .I services
 .SH DESCRIPTION
 .I services
-consist of one or more arguments. Each
+consists of one or more arguments. Each
 .I service
 directory must start with a slash.
 .P
 .B svwaitdown
-checks each
+sends each
 .I service
-given at the command line for being down.
+given at the command line the ``down'' command if not yet done, and waits
+for it to become down.
 The
 .I services
 given at the command line must be controlled by
@@ -57,7 +58,10 @@ processes to send the
 a KILL signal.
 .TP
 .B \-x
-Exit. Wait for the corresponding
+Exit. Send each
+.I service
+the ``exit'' command additionally to the ``down'' command, and wait for the
+corresponding
 .BR runsv (8)
 processes to exit instead for the
 .I services
@@ -97,11 +101,14 @@ returns 111 if the timeout
 .I sec
 was reached.
 .SH SEE ALSO
-svwaitup(8),
+svwaitdown(8),
+runsv(8),
+runsvctrl(8),
+runsvstat(8),
+runsvdir(8),
+runsvchdir(8),
 runit(8),
 runit-init(8),
-runsvdir(8),
-runsv(8),
 supervise(8),
 svscan(8)
 .P
diff --git a/man/svwaitup.8 b/man/svwaitup.8
@@ -86,10 +86,13 @@ increases the exit code by one and exits non zero. The maximum is 100.
 returns 111 on error.
 .SH SEE ALSO
 svwaitdown(8),
+runsv(8),
+runsvctrl(8),
+runsvstat(8),
+runsvdir(8),
+runsvchdir(8),
 runit(8),
 runit-init(8),
-runsvdir(8),
-runsv(8),
 supervise(8),
 svscan(8)
 .P
diff --git a/man/utmpset.8 b/man/utmpset.8
@@ -45,10 +45,14 @@ to the wtmp file.
 .B utmpset
 returns 111 on error, 1 on wrong usage, 0 in all other cases.
 .SH SEE ALSO
+runsv(8),
+runsvctrl(8),
+runsvstat(8),
+runsvdir(8),
+runsvchdir(8),
 runit(8),
 runit-init(8),
-svwaitdown(8),
-svwaitup(8)
+getty(8)
 .P
 http://smarden.org/runit/
 .SH AUTHOR
diff --git a/package/CHANGES b/package/CHANGES
@@ -1,3 +1,14 @@
+runit 0.9.0
+Thu, 24 Apr 2003 13:11:50 +0200
+  * runsvdir.c: don't propagate sig_term to runsv processes when receiving
+    sig_term; send sig_term to all runsv processes and exit 111 when
+    receiving sig_hangup.
+  * svlogd.c: code cleanup.
+  * svwaitdown.c: send command "d" (and "x" if -x is set) to a service if
+    it's not in state 'want down'.
+  * svwaitup.c: minor code cleanup.
+  * man/runsvdir.8, man/svwaitdown.8: adapt.
+
 runit 0.8.4
 Sun, 20 Apr 2003 19:31:24 +0200
   * svlogd.c: new; runit's service logging daemon.
diff --git a/package/commands b/package/commands
@@ -5,4 +5,5 @@ runsvdir
 runsvchdir
 svwaitdown
 svwaitup
+svlogd
 utmpset
diff --git a/package/upgrade b/package/upgrade
@@ -7,9 +7,9 @@ test -d src || ( echo 'Wrong working directory.'; exit 1 )
 here=`env - PATH=$PATH pwd`
 parent=`dirname $here`
 
-echo 'Creating symlink runit -> runit-0.8.4...'
+echo 'Creating symlink runit -> runit-0.9.0...'
 rm -f runit
-ln -s runit-0.8.4 runit
+ln -s runit-0.9.0 runit
 mv -f runit ..
 
 echo 'Making command links in /command...'
diff --git a/src/runsvdir.c b/src/runsvdir.c
@@ -51,6 +51,7 @@ void warn3x(char *m1, char *m2, char *m3) {
   strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, m3, 0);
 } 
 void s_term() { exitsoon =1; }
+void s_hangup() { exitsoon =2; }
 
 void runsv(int no, char *name) {
   int pid;
@@ -69,6 +70,8 @@ void runsv(int no, char *name) {
     if (log)
       if (fd_move(2, logpipe[1]) == -1)
 	warn("unable to set filedescriptor for log service", 0);
+    sig_uncatch(sig_hangup);
+    sig_uncatch(sig_term);
     pathexec_run(*prog, prog, (const char* const*)environ);
     fatal("unable to start runsv ", name);
   }
@@ -171,6 +174,7 @@ int main(int argc, char **argv) {
   if (! argv || ! *argv) usage();
 
   sig_catch(sig_term, s_term);
+  sig_catch(sig_hangup, s_hangup);
   svdir =*argv++;
   if (argv && *argv) {
     log =*argv;
@@ -257,9 +261,12 @@ int main(int argc, char **argv) {
 	  log[loglen -1] =ch;
 	}
       }
-    if (exitsoon) {
-      for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
+    switch(exitsoon) {
+    case 1:
       _exit(0);
+    case 2:
+      for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
+      _exit(111);
     }
   }
   /* not reached */
diff --git a/src/svlogd.c b/src/svlogd.c
@@ -95,7 +95,7 @@ void pause2(char *m0, char *m1) {
   sleep(3);
 }
 
-int processorstart(struct logdir *ld) {
+unsigned int processorstart(struct logdir *ld) {
   int pid;
 
   if (! ld->processor.len) return(0);
@@ -126,8 +126,17 @@ int processorstart(struct logdir *ld) {
       fatal2("unable to open output for processor", ld->name);
     if (fd_move(1, fd) == -1)
       fatal2("unable to move filedescriptor for processor", ld->name);
-    if ((fd =open_read("state")) == -1)
-      fatal2("unable to open state for processor", ld->name);
+    if ((fd =open_read("state")) == -1) {
+      if (errno == error_noent) {
+	if ((fd =open_trunc("state")) == -1)
+	  fatal2("unable to create empty state for processor", ld->name);
+	close(fd);
+	if ((fd =open_read("state")) == -1)
+	  fatal2("unable to open state for processor", ld->name);
+      }
+      else
+	fatal2("unable to open state for processor", ld->name);
+    }
     if (fd_move(4, fd) == -1)
       fatal2("unable to move filedescriptor for processor", ld->name);
     if ((fd =open_trunc("newstate")) == -1)
@@ -145,7 +154,7 @@ int processorstart(struct logdir *ld) {
   ld->ppid =pid;
   return(1);  
 }
-int processorstop(struct logdir *ld) {
+unsigned int processorstop(struct logdir *ld) {
   char f[28];
 
   if (ld->ppid) {
@@ -181,7 +190,7 @@ int processorstop(struct logdir *ld) {
   return(1);
 }
 
-int rotate(struct logdir *ld) {
+unsigned int rotate(struct logdir *ld) {
   DIR *d;
   direntry *f;
   int n =0;
@@ -243,13 +252,10 @@ int rotate(struct logdir *ld) {
   if (ld->nmax && (n >= ld->nmax)) {
     if (verbose)
       strerr_warn5(INFO, "delete: ", ld->name, "/", oldest, 0);
-    if (*oldest && (unlink(oldest) == -1))
+    if ((*oldest == '@') && (unlink(oldest) == -1))
       warn2("unable to unlink oldest logfile", ld->name);
   }
 
-  /*
-    start processor
-  */
   if (ld->processor.len) {
     processorstart(ld);
   }
@@ -276,7 +282,7 @@ void logdir_close(struct logdir *ld) {
   ld->fdlock =-1;
 }
 
-int logdir_open(struct logdir *ld, const char *fn) {
+unsigned int logdir_open(struct logdir *ld, const char *fn) {
   if ((ld->fddir =open_read(fn)) == -1) {
     warn2("unable to open log directory", (char*)fn);
     return(0);
@@ -330,10 +336,13 @@ int logdir_open(struct logdir *ld, const char *fn) {
 	break;
       case 's':
 	scan_ulong(&sa.s[i +1], &ld->sizemax);
-	if (ld->sizemax < 2048) ld->sizemax =2048;
+	/*
+	  if (ld->sizemax && (ld->sizemax < linelen)) ld->sizemax =2 *linelen;
+	*/
 	break;
       case 'n':
 	scan_ulong(&sa.s[i +1], &ld->nmax);
+	if (ld->nmax == 1) ld->nmax =2;
 	break;
       case '!':
 	while (! stralloc_copys(&ld->processor, &sa.s[i +1]))
@@ -373,8 +382,6 @@ int logdir_open(struct logdir *ld, const char *fn) {
   coe(ld->fdcur);
   while (fchmod(ld->fdcur, 0644) == -1)
     pause2("unable to set mode of current", ld->name);
-  if (! ld->btmp) 
-    while (! (ld->btmp =(char*)alloc(buflen *sizeof(char)))) pause_nomem();
   buffer_init(&ld->b, buffer_unixwrite, ld->fdcur, ld->btmp, sizeof ld->btmp);
   
   if (verbose) {
@@ -396,7 +403,7 @@ void logdirs_reopen(void) {
   }
 }
 
-int linestart(struct logdir *ld, char *s, int len) {
+unsigned int linestart(struct logdir *ld, char *s, int len) {
   /* check inst, set match */
   ld->match ='+';
   if (ld->inst.len) {
@@ -436,14 +443,14 @@ int linestart(struct logdir *ld, char *s, int len) {
   ld->size +=len;
   return(1);
 }
-int lineadd(struct logdir *ld, char *s, int len) {
+unsigned int lineadd(struct logdir *ld, char *s, int len) {
   if (ld->match != '+') return(0);
   buffer_put(&ld->b, s, len);
   ld->size +=len;
   if (ld->sizemax && (ld->size >= ld->sizemax)) rotate(ld);
   return(1);
 }
-int lineflush(struct logdir *ld, char *s, int len) {
+unsigned int lineflush(struct logdir *ld, char *s, int len) {
   switch(ld->match) {
   case '-':
     return(0);
@@ -459,15 +466,19 @@ int lineflush(struct logdir *ld, char *s, int len) {
     buffer_putflush(&ld->b, "\n", 1);
     ld->size +=1;
     ld->match =0;
-    if (ld->sizemax && (ld->size >= (ld->sizemax -linelen))) rotate(ld);
+    if (ld->sizemax)
+      if ((linelen > ld->sizemax) || (ld->size >= (ld->sizemax -linelen)))
+	rotate(ld);
     return(1);
   }
   return(0);
 }
 int buffer_pread(int fd, char *s, unsigned int len) {
-  len =read(fd, s, len);
-  if ((len == -1) && (errno == error_intr)) return(0);
-  return(len);
+  int rc;
+
+  rc =read(fd, s, len);
+  if ((rc == -1) && (errno == error_intr)) return(0);
+  return(rc);
 }
 void sig_term_handler(void) {
   exitasap =1;
@@ -545,7 +556,9 @@ int main(int argc, const char **argv) {
   if (! dir) die_nomem();
   for (i =0; i < dirn; ++i) {
     dir[i].fddir =-1;
-    dir[i].btmp =0; /* grm */
+    dir[i].btmp =(char*)alloc(buflen *sizeof(char));
+    if (! dir[i].btmp) die_nomem();
+    dir[i].ppid =0;
   }
   databuf =(char*)alloc(buflen *sizeof(char));
   if (! databuf) die_nomem();
@@ -569,12 +582,7 @@ int main(int argc, const char **argv) {
     int r, len;
     char *ch;
 
-    if (exitasap) {
-      /* check for processors */
-      for (i =0; i < dirn; ++i)
-	if (dir[i].ppid) while (! processorstop(&dir[i]));
-      break;
-    }
+    if (exitasap && ! data.p) break; /* buffer is empty */
 
     sig_unblock(sig_term);
     sig_unblock(sig_child);
@@ -608,7 +616,7 @@ int main(int argc, const char **argv) {
 	stamp[26] =0;
 	break;
       case 3:
-	stamp[fmt_ptime(stamp, &now)] =' ';
+	stamp[fmt_ptime(stamp, &now)] =0;
 	stamp[19] =' '; stamp[20] =0;
 	break;
       }
@@ -646,8 +654,7 @@ int main(int argc, const char **argv) {
   }
   
   for (i =0; i < dirn; ++i) {
-    if (dir[i].fddir != -1)
-      buffer_flush(&dir[i].b);
+    if (dir[i].ppid) while (! processorstop(&dir[i]));
     logdir_close(&dir[i]);
   }
   _exit(0);
diff --git a/src/svwaitdown.c b/src/svwaitdown.c
@@ -10,7 +10,7 @@
 #define FATAL "svwaitdown: fatal: "
 #define WARNING "svwaitdown: warning: "
 #define INFO "svwaitdown: "
-#define USAGE " [ -v ] [ -t 2..6000 ] service ..."
+#define USAGE " [-v] [-t 2..6000] service ..."
 
 #define VERSION "$Id$"
 
@@ -18,22 +18,21 @@ const char *progname;
 const char * const *dir;
 unsigned int rc =0;
 
-void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
 
-void warn (const char *s1, const char *s2, struct strerr *e) {
-  dir++;
-  rc++;
+void warn(const char *s1, const char *s2, struct strerr *e) {
+  dir++; rc++;
   strerr_warn3(WARNING, s1, s2, e);
 }
 
-int main (int argc, const char * const *argv) {
+int main(int argc, const char * const *argv) {
   int opt;
   unsigned long sec =600;
   int verbose =0;
   int doexit =0;
   int dokill =0;
   int fd;
-  char status[18];
+  char status[20];
   int r;
   unsigned long pid;
   struct tai start;
@@ -76,7 +75,6 @@ int main (int argc, const char * const *argv) {
       warn(*dir, ": unable to change directory: ", &strerr_sys);
       continue;
     }
-    
     if ((fd =open_write("supervise/ok")) == -1) {
       if (errno == error_nodevice) {
 	if (verbose) strerr_warn3(INFO, *dir, ": supervise not running.", 0);
@@ -88,31 +86,42 @@ int main (int argc, const char * const *argv) {
     }
     close(fd);
 
-    if (! doexit) {
-      if ((fd =open_read("supervise/status")) == -1) {
-	warn(*dir, "unable to open supervise/status: ", &strerr_sys);
-	continue;
-      }
-      r =buffer_unixread(fd, status, sizeof status);
-      close(fd);
-      if (r < sizeof status) {
-	if (r == -1)
-	  warn(*dir, "unable to read supervise/status: ", &strerr_sys);
-	else
-	  warn(*dir, ": unable to read supervise/status: bad format.", 0);
+    if ((fd =open_read("supervise/status")) == -1) {
+      warn(*dir, "unable to open supervise/status: ", &strerr_sys);
+      continue;
+    }
+    r =buffer_unixread(fd, status, 20);
+    close(fd);
+    if ((r < 18) || (r == 19)) { /* supervise compatibility */
+      if (r == -1)
+	warn(*dir, "unable to read supervise/status: ", &strerr_sys);
+      else
+	warn(*dir, ": unable to read supervise/status: bad format.", 0);
+      continue;
+    }
+    pid =(unsigned char)status[15];
+    pid <<=8; pid +=(unsigned char)status[14];
+    pid <<=8; pid +=(unsigned char)status[13];
+    pid <<=8; pid +=(unsigned char)status[12];
+
+    if (! doexit && ! pid) {
+      /* ok, service is down */
+      if (verbose) strerr_warn3(INFO, *dir, ": down.", 0);
+      dir++;
+      continue;
+    }
+
+    if (status[17] != 'd') {
+      if ((fd =open_write("supervise/control")) == -1) {
+	warn(*dir, ": unable to open supervise/control: ", &strerr_sys);
 	continue;
       }
-      pid =(unsigned char)status[15];
-      pid <<=8; pid +=(unsigned char)status[14];
-      pid <<=8; pid +=(unsigned char)status[13];
-      pid <<=8; pid +=(unsigned char)status[12];
-      if (! pid) {
-	/* ok, service is down */
-	if (verbose) strerr_warn3(INFO, *dir, ": down.", 0);
-	dir++;
+      if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
+	warn(*dir, ": unable to write to supervise/control: ", &strerr_sys);
 	continue;
       }
     }
+  
     tai_now(&now);
     tai_sub(&now, &now, &start);
     if (tai_approx(&now) >= sec) {
diff --git a/src/svwaitup.c b/src/svwaitup.c
@@ -10,22 +10,21 @@
 #define FATAL "svwaitup: fatal: "
 #define WARNING "svwaitup: warning: "
 #define INFO "svwaitup: "
-#define USAGE " [ -v ] [ -s 2..600 ] service ..."
+#define USAGE " [-v] [-s 2..600] service ..."
 
 const char *progname;
 unsigned long sec =2;
 unsigned int rc =0;
 const char * const *dir;
 
-void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
 
-void warn (const char *s1, const char *s2, struct strerr *e) {
-  dir++;
-  rc++;
+void warn(const char *s1, const char *s2, struct strerr *e) {
+  dir++; rc++;
   strerr_warn3(WARNING, s1, s2, e);
 }
 
-int main (int argc, const char * const *argv) {
+int main(int argc, const char * const *argv) {
   int opt;
   int verbose =0;
   char status[18];
@@ -66,7 +65,6 @@ int main (int argc, const char * const *argv) {
       warn(*dir, ": unable to change directory: ", &strerr_sys);
       continue;
     }
-    
     if ((fd =open_write("supervise/ok")) == -1) {
       if (errno == error_nodevice)
 	warn(*dir, ": supervise not running.", 0);