about summary refs log tree commit diff
path: root/src/supervision/s6-supervise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/supervision/s6-supervise.c')
-rw-r--r--src/supervision/s6-supervise.c89
1 files changed, 54 insertions, 35 deletions
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
index 7036a6d..fa96a02 100644
--- a/src/supervision/s6-supervise.c
+++ b/src/supervision/s6-supervise.c
@@ -40,7 +40,7 @@ enum trans_e
 {
   V_TIMEOUT, V_CHLD, V_TERM, V_HUP, V_QUIT, V_INT,
   V_a, V_b, V_q, V_h, V_k, V_t, V_i, V_1, V_2, V_p, V_c, V_y, V_r,
-  V_o, V_d, V_u, V_x, V_O
+  V_o, V_d, V_u, V_D, V_U, V_x, V_O
 } ;
 
 typedef enum state_e state_t, *state_t_ref ;
@@ -165,6 +165,20 @@ static void closethem (void)
       strerr_warnwu2sys("open /dev/null for ", "writing") ;
 }
 
+static void adddown (void)
+{
+  if (!openwritenclose_unsafe("down", "", 0))
+    strerr_warnwu2sys("create ", "./down file") ;
+}
+
+static void deldown (void)
+{
+  int e = errno ;
+  if (unlink("down") == -1 && errno != ENOENT)
+    strerr_warnwu2sys("unlink ", "./down file") ;
+  errno = e ;
+}
+
 static void killa (void)
 {
   kill(status.pid, SIGALRM) ;
@@ -390,35 +404,46 @@ static void trystart (void)
   if (lfd >= 0) fd_close(lfd) ;
 }
 
-static void downtimeout (void)
+static void wantdown (void)
 {
-  if (status.flagwantup) trystart() ;
-  else settimeout_infinite() ;
+  status.flagwantup = 0 ;
+  announce() ;
 }
 
-static void down_O (void)
+static void wantup (void)
 {
-  status.flagwantup = 0 ;
+  status.flagwantup = 1 ;
   announce() ;
 }
 
+static void downtimeout (void)
+{
+  if (status.flagwantup) trystart() ;
+  else settimeout_infinite() ;
+}
+
 static void down_o (void)
 {
-  down_O() ;
+  wantdown() ;
   trystart() ;
 }
 
 static void down_u (void)
 {
-  status.flagwantup = 1 ;
-  announce() ;
+  wantup() ;
   trystart() ;
 }
 
-static void down_d (void)
+static void down_D (void)
 {
-  status.flagwantup = 0 ;
-  announce() ;
+  adddown() ;
+  wantdown() ;
+}
+
+static void down_U (void)
+{
+  deldown() ;
+  down_u() ;
 }
 
 static int uplastup_z (void)
@@ -512,12 +537,6 @@ static void uptimeout (void)
   }
 }
 
-static void up_o (void)
-{
-  status.flagwantup = 0 ;
-  announce() ;
-}
-
 static void up_d (void)
 {
   tain tto ;
@@ -534,10 +553,16 @@ static void up_d (void)
   else settimeout_infinite() ;
 }
 
-static void up_u (void)
+static void up_D (void)
 {
-  status.flagwantup = 1 ;
-  announce() ;
+  adddown() ;
+  up_d() ;
+}
+
+static void up_U (void)
+{
+  deldown() ;
+  wantup() ;
 }
 
 static void up_x (void)
@@ -570,12 +595,6 @@ static void finish_z (void)
   else set_down_and_ready("D", 1) ;
 }
 
-static void finish_u (void)
-{
-  status.flagwantup = 1 ;
-  announce() ;
-}
-
 static void finish_x (void)
 {
   state = LASTFINISH ;
@@ -588,23 +607,23 @@ static void lastfinish_z (void)
   bail() ;
 }
 
-static action_t_ref const actions[5][24] =
+static action_t_ref const actions[5][26] =
 {
   { &downtimeout, &nop, &bail, &bail, &bail, &bail,
     &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop,
-    &down_o, &down_d, &down_u, &bail, &down_O },
+    &down_o, &wantdown, &down_u, &down_D, &down_U, &bail, &wantdown },
   { &uptimeout, &up_z, &up_term, &up_x, &bail, &sigint,
     &killa, &killb, &killq, &killh, &killk, &killt, &killi, &kill1, &kill2, &killp, &killc, &killy, &killr,
-    &up_o, &up_d, &up_u, &up_x, &up_o },
+    &wantdown, &up_d, &wantup, &up_D, &up_U, &up_x, &wantdown },
   { &finishtimeout, &finish_z, &finish_x, &finish_x, &bail, &sigint,
     &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop,
-    &up_o, &down_d, &finish_u, &finish_x, &up_o },
+    &wantdown, &wantdown, &wantup, &down_D, &up_U, &finish_x, &wantdown },
   { &uptimeout, &lastup_z, &up_d, &closethem, &bail, &sigint,
     &killa, &killb, &killq, &killh, &killk, &killt, &killi, &kill1, &kill2, &killp, &killc, &killy, &killr,
-    &up_o, &up_d, &nop, &closethem, &up_o },
+    &wantdown, &up_d, &wantup, &up_D, &up_U, &closethem, &wantdown },
   { &finishtimeout, &lastfinish_z, &nop, &closethem, &bail, &sigint,
     &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop, &nop,
-    &nop, &nop, &nop, &closethem, &nop }
+    &wantdown, &wantdown, &wantup, &down_D, &up_U, &closethem, &wantdown }
 } ;
 
 
@@ -687,8 +706,8 @@ static inline void handle_control (int fd)
     else if (!r) break ;
     else
     {
-      size_t pos = byte_chr("abqhkti12pcyroduxO", 18, c) ;
-      if (pos < 18) (*actions[state][V_a + pos])() ;
+      size_t pos = byte_chr("abqhkti12pcyroduDUxO", 20, c) ;
+      if (pos < 20) (*actions[state][V_a + pos])() ;
     }
   }
 }