Просмотр исходного кода

ncd: modules: runonce: add term_on_deinit option

ambrop7 14 лет назад
Родитель
Сommit
bbeb970f2c
1 измененных файлов с 32 добавлено и 3 удалено
  1. 32 3
      ncd/modules/runonce.c

+ 32 - 3
ncd/modules/runonce.c

@@ -30,13 +30,16 @@
  * 
  * Imperative program execution module. On initialization, starts the process.
  * Goes to UP state when the process terminates. When requested to die, waits for
- * the process to terminate if it's running, without sending any signals.
+ * the process to terminate if it's running, optionally sending SIGTERM.
  * 
- * Synopsis: runonce(list(string) cmd)
+ * Synopsis: runonce(list(string) cmd, [list opts])
  * Arguments:
  *   cmd - Command to run on startup. The first element is the full path
  *     to the executable, other elements are command line arguments (excluding
  *     the zeroth argument).
+ *   opts - List of options:
+ *     "term_on_deinit" - If we get a deinit request while the process is running,
+ *                        send it SIGTERM.
  * Variables:
  *   string exit_status - if the program exited normally, the non-negative exit code, otherwise -1
  */
@@ -59,6 +62,7 @@
 
 struct instance {
     NCDModuleInst *i;
+    int term_on_deinit;
     int state;
     BProcess process;
     int exit_status;
@@ -165,14 +169,34 @@ static void func_new (NCDModuleInst *i)
     
     // init arguments
     o->i = i;
+    o->term_on_deinit = 0;
     
     // read arguments
     NCDValue *cmd_arg;
-    if (!NCDValue_ListRead(i->args, 1, &cmd_arg)) {
+    NCDValue *opts_arg = NULL;
+    if (!NCDValue_ListRead(i->args, 1, &cmd_arg) && !NCDValue_ListRead(i->args, 2, &cmd_arg, &opts_arg)) {
         ModuleLog(i, BLOG_ERROR, "wrong arity");
         goto fail1;
     }
     
+    // read options
+    for (NCDValue *opt = (opts_arg ? NCDValue_ListFirst(opts_arg) : NULL); opt; opt = NCDValue_ListNext(opts_arg, opt)) {
+        // read name
+        if (NCDValue_Type(opt) != NCDVALUE_STRING) {
+            ModuleLog(o->i, BLOG_ERROR, "wrong option name type");
+            goto fail1;
+        }
+        char *optname = NCDValue_StringValue(opt);
+        
+        if (!strcmp(optname, "term_on_deinit")) {
+            o->term_on_deinit = 1;
+        }
+        else {
+            ModuleLog(o->i, BLOG_ERROR, "unknown option name");
+            goto fail1;
+        }
+    }
+    
     // build cmdline
     char *exec;
     CmdLine cl;
@@ -223,6 +247,11 @@ static void func_die (void *vo)
         return;
     }
     
+    // send SIGTERM if requested
+    if (o->term_on_deinit) {
+        BProcess_Terminate(&o->process);
+    }
+    
     o->state = STATE_RUNNING_DIE;
 }