commit 25456755fdebf3dc466380f0dac8f663c9b56ea2
parent 32705d016c867bedd5604e9acbed060b022ddf0d
Author: Gerrit Pape <pape@smarden.org>
Date: Sun, 12 Dec 2004 20:14:26 +0000
* runsv.check, runsv.dist: check custom control commands.
minor.
Diffstat:
6 files changed, 72 insertions(+), 49 deletions(-)
diff --git a/doc/runsv.8.html b/doc/runsv.8.html
@@ -109,21 +109,28 @@ Example: to send a TERM signal to the socklog-unix service, either do
If <i><b>echo</b>(1)</i> on your systems does not provide the -n option, leave it out,
<b>runsv</b> ignores unknown characters written to the control pipe. <i><b>echo</b>(1)</i> usually
blocks if no <b>runsv</b> process is running in the service directory.
-<h2><a name='sect4'>Signals</a></h2>
-If
-<b>runsv</b> receives a TERM signal, it acts as if the character x was written
-to the control pipe.
-<h2><a name='sect5'>Exit Codes</a></h2>
-<b>runsv</b> exits 111 on an error on startup or
-if another <b>runsv</b> is running in <i>service</i>. <p>
-<b>runsv</b> exits 0 if it was told to
-exit.
-<h2><a name='sect6'>See Also</a></h2>
-<i>runsvctrl(8)</i>, <i>runsvstat(8)</i>, <i>chpst(8)</i>, <i>svlogd(8)</i>, <i>runit(8)</i>,
-<i>runit-init(8)</i>, <i>runsvdir(8)</i>, <i>runsvchdir(8)</i>, <i>utmpset(8)</i> <p>
-<i>http://smarden.org/runit/</i>
-
-<h2><a name='sect7'>Author</a></h2>
+<h2><a name='sect4'>Customize
+Control</a></h2>
+For each control character <i>c</i> sent to the control pipe, <b>runsv</b> first
+checks if <i>service/control/<i>c</i> exists and is executable. If so, it starts <i>service</i>/control/<i>c</i>
+and waits for it to terminate, before interpreting the command. If the program
+exits with return code 0, <b>runsv</b> refrains from sending the service the corresponding
+signal. The command <i>o</i> is always considered as command <i>u</i>. The control of the
+optional log service cannot be customized.
+<h2><a name='sect5'></i>Signals</a></h2>
+If <b>runsv</b> receives a TERM
+signal, it acts as if the character x was written to the control pipe.
+<h2><a name='sect6'>Exit
+Codes</a></h2>
+<b>runsv</b> exits 111 on an error on startup or if another <b>runsv</b> is running
+in <i>service</i>. <p>
+<b>runsv</b> exits 0 if it was told to exit.
+<h2><a name='sect7'>See Also</a></h2>
+<i>runsvctrl(8)</i>, <i>runsvstat(8)</i>,
+<i>chpst(8)</i>, <i>svlogd(8)</i>, <i>runit(8)</i>, <i>runit-init(8)</i>, <i>runsvdir(8)</i>, <i>runsvchdir(8)</i>,
+<i>utmpset(8)</i> <p>
+<i>http://smarden.org/runit/</i>
+<h2><a name='sect8'>Author</a></h2>
Gerrit Pape <pape@smarden.org> <p>
<hr><p>
@@ -133,10 +140,11 @@ Gerrit Pape <pape@smarden.org> <p>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Control</a></li>
-<li><a name='toc4' href='#sect4'>Signals</a></li>
-<li><a name='toc5' href='#sect5'>Exit Codes</a></li>
-<li><a name='toc6' href='#sect6'>See Also</a></li>
-<li><a name='toc7' href='#sect7'>Author</a></li>
+<li><a name='toc4' href='#sect4'>Customize Control</a></li>
+<li><a name='toc5' href='#sect5'>Signals</a></li>
+<li><a name='toc6' href='#sect6'>Exit Codes</a></li>
+<li><a name='toc7' href='#sect7'>See Also</a></li>
+<li><a name='toc8' href='#sect8'>Author</a></li>
</ul>
</body>
</html>
diff --git a/man/runsv.8 b/man/runsv.8
@@ -175,12 +175,7 @@ The command
.I o
is always considered as command
.IR u .
-The
-.IR u ,
-.IR e ,
-and
-.I x
-commands of an optional log service cannot be customized.
+The control of the optional log service cannot be customized.
.SH SIGNALS
If
.B runsv
diff --git a/package/CHANGES b/package/CHANGES
@@ -4,6 +4,7 @@ runit 1.2.0
* runsv.c: support custom control commands through control/ directory,
optionally switch off sending signal.
* man/runsv.8: document custom control commands.
+ * runsv.check, runsv.dist: check custom control commands.
runit 1.1.0
Sat, 06 Nov 2004 17:21:11 +0000
diff --git a/src/runsv.c b/src/runsv.c
@@ -138,14 +138,15 @@ void update_status(struct svdir *s) {
}
if (s->ctrl & C_PAUSE) buffer_puts(&b, ", paused");
if (s->ctrl & C_TERM) buffer_puts(&b, ", got TERM");
- switch(s->want) {
- case W_DOWN:
- if (s->state != S_DOWN) buffer_puts(&b, ", want down");
- break;
- case W_EXIT:
- buffer_puts(&b, ", want exit");
- break;
- }
+ if (s->state != S_DOWN)
+ switch(s->want) {
+ case W_DOWN:
+ buffer_puts(&b, ", want down");
+ break;
+ case W_EXIT:
+ buffer_puts(&b, ", want exit");
+ break;
+ }
buffer_putsflush(&b, "\n");
close(fd);
if (s->islog) {
@@ -201,15 +202,16 @@ void update_status(struct svdir *s) {
warn("unable to rename supervise/status.new to supervise/status");
}
}
-unsigned int custom(char c) {
+unsigned int custom(struct svdir *s, char c) {
int pid;
int w;
- char a[7];
+ char a[10];
struct stat st;
char *prog[2];
- byte_copy(a, 7, "ctrl/?");
- a[5] =c;
+ if (s->islog) return(0);
+ byte_copy(a, 10, "control/?");
+ a[8] =c;
if (stat(a, &st) == 0) {
if (st.st_mode & S_IXUSR) {
if ((pid =fork()) == -1) {
@@ -249,7 +251,7 @@ void startservice(struct svdir *s) {
run[0] ="./finish";
else {
run[0] ="./run";
- if (! s->islog) custom('u');
+ custom(s, 'u');
}
run[1] =0;
@@ -299,7 +301,7 @@ int ctrl(struct svdir *s, char c) {
case 'd': /* down */
s->want =W_DOWN;
update_status(s);
- if (s->pid && s->state != S_FINISH && ! custom(c)) stopservice(s);
+ if (s->pid && s->state != S_FINISH && ! custom(s, c)) stopservice(s);
break;
case 'u': /* up */
s->want =W_UP;
@@ -311,22 +313,22 @@ int ctrl(struct svdir *s, char c) {
if (s->islog) break;
s->want =W_EXIT;
update_status(s);
- if (s->pid && s->state != S_FINISH && ! custom(c)) stopservice(s);
+ if (s->pid && s->state != S_FINISH && ! custom(s, c)) stopservice(s);
break;
case 't': /* sig term */
- if (s->pid && s->state != S_FINISH && ! custom(c)) stopservice(s);
+ if (s->pid && s->state != S_FINISH && ! custom(s, c)) stopservice(s);
break;
case 'k': /* sig kill */
if (s->pid) kill(s->pid, SIGKILL);
s->state =S_DOWN;
break;
case 'p': /* sig pause */
- if (s->pid && ! custom(c)) kill(s->pid, SIGSTOP);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGSTOP);
s->ctrl |=C_PAUSE;
update_status(s);
break;
case 'c': /* sig cont */
- if (s->pid && ! custom(c)) kill(s->pid, SIGCONT);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGCONT);
if (s->ctrl & C_PAUSE) s->ctrl &=~C_PAUSE;
update_status(s);
break;
@@ -336,22 +338,22 @@ int ctrl(struct svdir *s, char c) {
if (! s->pid) startservice(s);
break;
case 'a': /* sig alarm */
- if (s->pid && ! custom(c)) kill(s->pid, SIGALRM);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGALRM);
break;
case 'h': /* sig hup */
- if (s->pid && ! custom(c)) kill(s->pid, SIGHUP);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGHUP);
break;
case 'i': /* sig int */
- if (s->pid && ! custom(c)) kill(s->pid, SIGINT);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGINT);
break;
case 'q': /* sig quit */
- if (s->pid && ! custom(c)) kill(s->pid, SIGQUIT);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGQUIT);
break;
case '1': /* sig usr1 */
- if (s->pid && ! custom(c)) kill(s->pid, SIGUSR1);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR1);
break;
case '2': /* sig usr2 */
- if (s->pid && ! custom(c)) kill(s->pid, SIGUSR2);
+ if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR2);
break;
}
return(1);
diff --git a/src/runsv.check b/src/runsv.check
@@ -13,6 +13,13 @@ runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
cat "${ctmp}"/supervise/stat
+mkdir -p "${ctmp}"/control
+echo '#!/bin/sh' >"${ctmp}"/control/t
+echo 'echo term' >>"${ctmp}"/control/t
+echo 'exit 1' >>"${ctmp}"/control/t
+chmod 700 "${ctmp}"/control/t
+echo t >"${ctmp}"/supervise/control
+sleep 2
echo x >"${ctmp}"/supervise/control
wait
echo $?
@@ -24,6 +31,13 @@ chmod 700 "${ctmp}"/log/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/log/supervise/stat || sleep 2
+mkdir -p "${ctmp}"/control
+echo '#!/bin/sh' >"${ctmp}"/control/i
+echo 'echo no interrupt' >>"${ctmp}"/control/i
+echo 'exit 0' >>"${ctmp}"/control/i
+chmod 700 "${ctmp}"/control/i
+echo i >"${ctmp}"/supervise/control
+sleep 1
echo x >"${ctmp}"/supervise/control
wait
echo $?
diff --git a/src/runsv.dist b/src/runsv.dist
@@ -3,8 +3,11 @@ usage: runsv dir
1
starting
run
+term
+starting
0
0
starting
+no interrupt
0
starting