|
@@ -31,58 +31,47 @@
|
|
|
#define STATE_DELETING_LOCK 5
|
|
#define STATE_DELETING_LOCK 5
|
|
|
#define STATE_DELETING 6
|
|
#define STATE_DELETING 6
|
|
|
|
|
|
|
|
-static int start_process (command_template_instance *o, int remove);
|
|
|
|
|
|
|
+static void lock_handler (command_template_instance *o);
|
|
|
static void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status);
|
|
static void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status);
|
|
|
static void free_template (command_template_instance *o, int is_error);
|
|
static void free_template (command_template_instance *o, int is_error);
|
|
|
|
|
|
|
|
-int start_process (command_template_instance *o, int remove)
|
|
|
|
|
-{
|
|
|
|
|
- int ret = 0;
|
|
|
|
|
-
|
|
|
|
|
- // build command line
|
|
|
|
|
- char *exec;
|
|
|
|
|
- CmdLine cl;
|
|
|
|
|
- if (!(o->build_cmdline(o->i, remove, &exec, &cl))) {
|
|
|
|
|
- NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "build_cmdline callback failed");
|
|
|
|
|
- goto fail0;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // start process
|
|
|
|
|
- if (!BProcess_Init(&o->process, o->i->manager, (BProcess_handler)process_handler, o, exec, CmdLine_Get(&cl), NULL)) {
|
|
|
|
|
- NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "BProcess_Init failed");
|
|
|
|
|
- goto fail1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ret = 1;
|
|
|
|
|
-
|
|
|
|
|
-fail1:
|
|
|
|
|
- CmdLine_Free(&cl);
|
|
|
|
|
- free(exec);
|
|
|
|
|
-fail0:
|
|
|
|
|
- return ret;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static void lock_handler (command_template_instance *o)
|
|
static void lock_handler (command_template_instance *o)
|
|
|
{
|
|
{
|
|
|
ASSERT(o->state == STATE_ADDING_LOCK || o->state == STATE_DELETING_LOCK)
|
|
ASSERT(o->state == STATE_ADDING_LOCK || o->state == STATE_DELETING_LOCK)
|
|
|
ASSERT(!o->have_process)
|
|
ASSERT(!o->have_process)
|
|
|
-
|
|
|
|
|
- int remove = (o->state == STATE_DELETING_LOCK);
|
|
|
|
|
-
|
|
|
|
|
- // start process
|
|
|
|
|
- if (!start_process(o, remove)) {
|
|
|
|
|
- free_template(o, 1);
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ ASSERT(!(o->state == STATE_ADDING_LOCK) || o->do_exec)
|
|
|
|
|
+ ASSERT(!(o->state == STATE_DELETING_LOCK) || o->undo_exec)
|
|
|
|
|
+
|
|
|
|
|
+ if (o->state == STATE_ADDING_LOCK) {
|
|
|
|
|
+ // start process
|
|
|
|
|
+ if (!BProcess_Init(&o->process, o->i->manager, (BProcess_handler)process_handler, o, o->do_exec, CmdLine_Get(&o->do_cmdline), NULL)) {
|
|
|
|
|
+ NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "BProcess_Init failed");
|
|
|
|
|
+ free_template(o, 1);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // set have process
|
|
|
|
|
+ o->have_process = 1;
|
|
|
|
|
+
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_ADDING;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // start process
|
|
|
|
|
+ if (!BProcess_Init(&o->process, o->i->manager, (BProcess_handler)process_handler, o, o->undo_exec, CmdLine_Get(&o->undo_cmdline), NULL)) {
|
|
|
|
|
+ NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "BProcess_Init failed");
|
|
|
|
|
+ free_template(o, 1);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // set have process
|
|
|
|
|
+ o->have_process = 1;
|
|
|
|
|
+
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_DELETING;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // set have process
|
|
|
|
|
- o->have_process = 1;
|
|
|
|
|
-
|
|
|
|
|
- // set state
|
|
|
|
|
- o->state = (remove ? STATE_DELETING : STATE_ADDING);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status)
|
|
|
|
|
|
|
+static void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status)
|
|
|
{
|
|
{
|
|
|
ASSERT(o->have_process)
|
|
ASSERT(o->have_process)
|
|
|
ASSERT(o->state == STATE_ADDING || o->state == STATE_ADDING_NEED_DELETE || o->state == STATE_DELETING)
|
|
ASSERT(o->state == STATE_ADDING || o->state == STATE_ADDING_NEED_DELETE || o->state == STATE_DELETING)
|
|
@@ -105,6 +94,7 @@ void process_handler (command_template_instance *o, int normally, uint8_t normal
|
|
|
|
|
|
|
|
switch (o->state) {
|
|
switch (o->state) {
|
|
|
case STATE_ADDING: {
|
|
case STATE_ADDING: {
|
|
|
|
|
+ // set state
|
|
|
o->state = STATE_DONE;
|
|
o->state = STATE_DONE;
|
|
|
|
|
|
|
|
// signal up
|
|
// signal up
|
|
@@ -112,11 +102,16 @@ void process_handler (command_template_instance *o, int normally, uint8_t normal
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
case STATE_ADDING_NEED_DELETE: {
|
|
case STATE_ADDING_NEED_DELETE: {
|
|
|
- // wait for lock
|
|
|
|
|
- BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
-
|
|
|
|
|
- // set state
|
|
|
|
|
- o->state = STATE_DELETING_LOCK;
|
|
|
|
|
|
|
+ if (o->undo_exec) {
|
|
|
|
|
+ // wait for lock
|
|
|
|
|
+ BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
+
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_DELETING_LOCK;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ free_template(o, 0);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
case STATE_DELETING: {
|
|
case STATE_DELETING: {
|
|
@@ -136,26 +131,68 @@ void command_template_new (command_template_instance *o, NCDModuleInst *i, comma
|
|
|
o->user = user;
|
|
o->user = user;
|
|
|
o->blog_channel = blog_channel;
|
|
o->blog_channel = blog_channel;
|
|
|
|
|
|
|
|
|
|
+ // build do command
|
|
|
|
|
+ if (!o->build_cmdline(o->i, 0, &o->do_exec, &o->do_cmdline)) {
|
|
|
|
|
+ NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "build_cmdline do callback failed");
|
|
|
|
|
+ goto fail0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // build undo command
|
|
|
|
|
+ if (!o->build_cmdline(o->i, 1, &o->undo_exec, &o->undo_cmdline)) {
|
|
|
|
|
+ NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "build_cmdline undo callback failed");
|
|
|
|
|
+ goto fail1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// init lock job
|
|
// init lock job
|
|
|
BEventLockJob_Init(&o->elock_job, elock, (BEventLock_handler)lock_handler, o);
|
|
BEventLockJob_Init(&o->elock_job, elock, (BEventLock_handler)lock_handler, o);
|
|
|
|
|
|
|
|
// set have no process
|
|
// set have no process
|
|
|
o->have_process = 0;
|
|
o->have_process = 0;
|
|
|
|
|
|
|
|
- // wait for lock
|
|
|
|
|
- BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
|
|
+ if (o->do_exec) {
|
|
|
|
|
+ // wait for lock
|
|
|
|
|
+ BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
+
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_ADDING_LOCK;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_DONE;
|
|
|
|
|
+
|
|
|
|
|
+ // signal up
|
|
|
|
|
+ NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
- // set state
|
|
|
|
|
- o->state = STATE_ADDING_LOCK;
|
|
|
|
|
|
|
+fail1:
|
|
|
|
|
+ if (o->do_exec) {
|
|
|
|
|
+ free(o->do_exec);
|
|
|
|
|
+ CmdLine_Free(&o->do_cmdline);
|
|
|
|
|
+ }
|
|
|
|
|
+fail0:
|
|
|
|
|
+ o->free_func(o->user, 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void free_template (command_template_instance *o, int is_error)
|
|
|
|
|
|
|
+static void free_template (command_template_instance *o, int is_error)
|
|
|
{
|
|
{
|
|
|
ASSERT(!o->have_process)
|
|
ASSERT(!o->have_process)
|
|
|
|
|
|
|
|
// free lock job
|
|
// free lock job
|
|
|
BEventLockJob_Free(&o->elock_job);
|
|
BEventLockJob_Free(&o->elock_job);
|
|
|
|
|
|
|
|
|
|
+ // free undo command
|
|
|
|
|
+ if (o->undo_exec) {
|
|
|
|
|
+ free(o->undo_exec);
|
|
|
|
|
+ CmdLine_Free(&o->undo_cmdline);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // free do command
|
|
|
|
|
+ if (o->do_exec) {
|
|
|
|
|
+ free(o->do_exec);
|
|
|
|
|
+ CmdLine_Free(&o->do_cmdline);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// call free function
|
|
// call free function
|
|
|
o->free_func(o->user, is_error);
|
|
o->free_func(o->user, is_error);
|
|
|
}
|
|
}
|
|
@@ -175,17 +212,23 @@ void command_template_die (command_template_instance *o)
|
|
|
case STATE_ADDING: {
|
|
case STATE_ADDING: {
|
|
|
ASSERT(o->have_process)
|
|
ASSERT(o->have_process)
|
|
|
|
|
|
|
|
|
|
+ // set state
|
|
|
o->state = STATE_ADDING_NEED_DELETE;
|
|
o->state = STATE_ADDING_NEED_DELETE;
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
case STATE_DONE: {
|
|
case STATE_DONE: {
|
|
|
ASSERT(!o->have_process)
|
|
ASSERT(!o->have_process)
|
|
|
|
|
|
|
|
- // wait for lock
|
|
|
|
|
- BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
-
|
|
|
|
|
- // set state
|
|
|
|
|
- o->state = STATE_DELETING_LOCK;
|
|
|
|
|
|
|
+ if (o->undo_exec) {
|
|
|
|
|
+ // wait for lock
|
|
|
|
|
+ BEventLockJob_Wait(&o->elock_job);
|
|
|
|
|
+
|
|
|
|
|
+ // set state
|
|
|
|
|
+ o->state = STATE_DELETING_LOCK;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ free_template(o, 0);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
} break;
|
|
} break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|