Browse Source

Implementation of watchdog with the ACTION

git-svn-id: https://klish.googlecode.com/svn/trunk@497 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 12 years ago
parent
commit
a8d33b0008

+ 0 - 1
clish.xsd

@@ -474,7 +474,6 @@
         <xs:sequence>
             <xs:element ref="ACTION" minOccurs="1"/>
         </xs:sequence>
-        <xs:attribute name="timeout" type="xs:string" use="required"/>
     </xs:complexType>
 
 

+ 3 - 0
clish/shell/private.h

@@ -44,8 +44,10 @@ struct clish_shell_s {
 	void *client_cookie; /* Client callback cookie */
 	clish_view_t *global; /* Reference to the global view. */
 	clish_command_t *startup; /* This is the startup command */
+	unsigned int idle_timeout; /* This is the idle timeout */
 	clish_command_t *wdog; /* This is the watchdog command */
 	unsigned int wdog_timeout; /* This is the watchdog timeout */
+	bool_t wdog_active; /* If watchdog is active now */
 	clish_shell_state_t state; /* The current state */
 	char *overview; /* Overview text for this shell */
 	tinyrl_t *tinyrl; /* Tiny readline instance */
@@ -119,3 +121,4 @@ void clish_shell__expand_viewid(const char *viewid, lub_bintree_t *tree,
 void clish_shell__init_pwd(clish_shell_pwd_t *pwd);
 void clish_shell__fini_pwd(clish_shell_pwd_t *pwd);
 int clish_shell_timeout_fn(tinyrl_t *tinyrl);
+int clish_shell_keypress_fn(tinyrl_t *tinyrl, int key);

+ 34 - 3
clish/shell/shell_execute.c

@@ -25,7 +25,8 @@ static clish_shell_builtin_fn_t
     clish_source_nostop,
     clish_history,
     clish_nested_up,
-    clish_nop;
+    clish_nop,
+    clish_wdog;
 
 static clish_shell_builtin_t clish_cmd_list[] = {
 	{"clish_close", clish_close},
@@ -35,6 +36,7 @@ static clish_shell_builtin_t clish_cmd_list[] = {
 	{"clish_history", clish_history},
 	{"clish_nested_up", clish_nested_up},
 	{"clish_nop", clish_nop},
+	{"clish_wdog", clish_wdog},
 	{NULL, NULL}
 };
 
@@ -187,6 +189,7 @@ int clish_shell_execute(clish_context_t *context, char **out)
 	sigset_t old_sigs;
 	struct sigaction old_sigint, old_sigquit;
 	clish_view_t *cur_view = clish_shell__get_view(this);
+	unsigned int saved_wdog_timeout = this->wdog_timeout;
 
 	assert(cmd);
 	action = clish_command__get_action(cmd);
@@ -299,6 +302,14 @@ int clish_shell_execute(clish_context_t *context, char **out)
 		}
 	}
 
+	/* Set appropriate timeout. Workaround: Don't turn on  watchdog
+	on the "set watchdog <timeout>" command itself. */
+	if (this->wdog_timeout && saved_wdog_timeout) {
+		tinyrl__set_timeout(this->tinyrl, this->wdog_timeout);
+		this->wdog_active = BOOL_TRUE;
+	} else
+		tinyrl__set_timeout(this->tinyrl, this->idle_timeout);
+
 error:
 	return result;
 }
@@ -343,7 +354,7 @@ int clish_shell_exec_action(clish_action_t *action,
 /*
  * Find out the previous view in the stack and go to it
  */
-static int clish_nested_up(clish_context_t *context, const lub_argv_t * argv)
+static int clish_nested_up(clish_context_t *context, const lub_argv_t *argv)
 {
 	clish_shell_t *this = context->shell;
 
@@ -366,8 +377,28 @@ static int clish_nested_up(clish_context_t *context, const lub_argv_t * argv)
 /*
  * Builtin: NOP function
  */
-static int clish_nop(clish_context_t *context, const lub_argv_t * argv)
+static int clish_nop(clish_context_t *context, const lub_argv_t *argv)
+{
+	return 0;
+}
+
+/*----------------------------------------------------------- */
+/*
+ * Builtin: Set watchdog timeout. The "0" to turn watchdog off.
+ */
+static int clish_wdog(clish_context_t *context, const lub_argv_t *argv)
 {
+	const char *arg = lub_argv__get_arg(argv, 0);
+	clish_shell_t *this = context->shell;
+
+	/* Turn off watchdog if no args */
+	if (!arg || ('\0' == *arg)) {
+		this->wdog_timeout = 0;
+		return 0;
+	}
+
+	this->wdog_timeout = (unsigned int)atoi(arg);
+
 	return 0;
 }
 

+ 3 - 1
clish/shell/shell_new.c

@@ -40,8 +40,10 @@ static void clish_shell_init(clish_shell_t * this,
 	this->client_cookie = cookie;
 	this->global = NULL;
 	this->startup = NULL;
+	this->idle_timeout = 0; /* No idle timeout by default */
 	this->wdog = NULL;
-	this->wdog_timeout = 0;
+	this->wdog_timeout = 0; /* No watchdog timeout by default */
+	this->wdog_active = BOOL_FALSE;
 	this->state = SHELL_STATE_INITIALISING;
 	this->overview = NULL;
 	this->tinyrl = clish_shell_tinyrl_new(istream, ostream, 0);

+ 3 - 1
clish/shell/shell_tinyrl.c

@@ -356,6 +356,8 @@ static void clish_shell_tinyrl_init(tinyrl_t * this)
 
 	/* Assign timeout callback */
 	tinyrl__set_timeout_fn(this, clish_shell_timeout_fn);
+	/* Assign keypress callback */
+	tinyrl__set_keypress_fn(this, clish_shell_keypress_fn);
 }
 
 /*-------------------------------------------------------- */
@@ -523,7 +525,7 @@ void clish_shell__set_utf8(clish_shell_t * this, bool_t utf8)
 void clish_shell__set_timeout(clish_shell_t *this, int timeout)
 {
 	assert(this);
-	tinyrl__set_timeout(this->tinyrl, timeout);
+	this->idle_timeout = timeout;
 }
 
 /*--------------------------------------------------------- */

+ 0 - 5
clish/shell/shell_tinyxml.cpp

@@ -704,18 +704,13 @@ static void process_wdog(clish_shell_t *shell,
 {
 	clish_view_t *v = (clish_view_t *)parent;
 	clish_command_t *cmd = NULL;
-	const char *timeout = element->Attribute("timeout");
 
 	assert(!shell->wdog);
-	assert(timeout);
 
 	/* create a command with NULL help */
 	cmd = clish_view_new_command(v, "watchdog", NULL);
 	clish_command__set_lock(cmd, BOOL_FALSE);
 
-	/* Set watchdog timeout */
-	clish_shell__set_wdog_timeout(shell, atoi(timeout));
-
 	/* Remember this command */
 	shell->wdog = cmd;
 

+ 32 - 5
clish/shell/shell_wdog.c

@@ -8,12 +8,39 @@
 #include "lub/string.h"
 
 /*----------------------------------------------------------------------- */
-int clish_shell_timeout_fn(tinyrl_t *this)
+int clish_shell_timeout_fn(tinyrl_t *tinyrl)
 {
-	tinyrl_crlf(this);
-	fprintf(stderr, "Warning: Activity timeout. The session will be closed.\n");
-	/* Return -1 to close session on timeout */
-	return -1;
+	clish_context_t *context = tinyrl__get_context(tinyrl);
+	clish_shell_t *this = context->shell;
+
+	/* Idle timeout */
+	if (!this->wdog_active) {
+		tinyrl_crlf(tinyrl);
+		fprintf(stderr, "Warning: Idle timeout. The session will be closed.\n");
+		/* Return -1 to close session on timeout */
+		return -1;
+	}
+
+	/* Watchdog timeout */
+	clish_shell_wdog(this);
+	this->wdog_active = BOOL_FALSE;
+	tinyrl__set_timeout(tinyrl, this->idle_timeout);
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------- */
+int clish_shell_keypress_fn(tinyrl_t *tinyrl, int key)
+{
+	clish_context_t *context = tinyrl__get_context(tinyrl);
+	clish_shell_t *this = context->shell;
+
+	if (this->wdog_active) {
+		this->wdog_active = BOOL_FALSE;
+		tinyrl__set_timeout(tinyrl, this->idle_timeout);
+	}
+
+	return 0;
 }
 
 /*----------------------------------------------------------- */

+ 1 - 0
tinyrl/private.h

@@ -19,6 +19,7 @@ struct _tinyrl {
 	unsigned end;
 	tinyrl_completion_func_t *attempted_completion_function;
 	tinyrl_timeout_fn_t *timeout_fn; /* timeout callback */
+	tinyrl_keypress_fn_t *keypress_fn; /* keypress callback */
 	int state;
 #define RL_STATE_COMPLETING (0x00000001)
 	char *kill_string;

+ 13 - 1
tinyrl/tinyrl.c

@@ -453,6 +453,7 @@ tinyrl_init(tinyrl_t * this,
 	this->end = 0;
 	this->attempted_completion_function = complete_fn;
 	this->timeout_fn = tinyrl_timeout_default;
+	this->keypress_fn = NULL;
 	this->state = 0;
 	this->kill_string = NULL;
 	this->echo_char = '\0';
@@ -671,7 +672,10 @@ static char *internal_readline(tinyrl_t * this,
 			key = tinyrl_getchar(this);
 			/* has the input stream terminated? */
 			if (key >= 0) { /* Real key pressed */
-				/* call the handler for this key */
+				/* Common callback for any key */
+				if (this->keypress_fn)
+					this->keypress_fn(this, key);
+				/* Call the handler for this key */
 				if (!this->handlers[key](this, key))
 					tinyrl_ding(this);
 				if (this->done) {
@@ -1314,12 +1318,20 @@ void tinyrl__set_timeout(tinyrl_t *this, int timeout)
 	tinyrl_vt100__set_timeout(this->term, timeout);
 }
 
+/*-------------------------------------------------------- */
 void tinyrl__set_timeout_fn(tinyrl_t *this,
 	tinyrl_timeout_fn_t *fn)
 {
 	this->timeout_fn = fn;
 }
 
+/*-------------------------------------------------------- */
+void tinyrl__set_keypress_fn(tinyrl_t *this,
+	tinyrl_keypress_fn_t *fn)
+{
+	this->keypress_fn = fn;
+}
+
 /*-------------------------------------------------------- */
 bool_t tinyrl_is_quoting(const tinyrl_t * this)
 {

+ 12 - 22
tinyrl/tinyrl.h

@@ -57,6 +57,7 @@ typedef char **tinyrl_completion_func_t(tinyrl_t * instance,
 	const char *text, unsigned start, unsigned end);
 
 typedef int tinyrl_timeout_fn_t(tinyrl_t *instance);
+typedef int tinyrl_keypress_fn_t(tinyrl_t *instance, int key);
 
 /**
  * \return
@@ -98,38 +99,27 @@ extern void *tinyrl__get_context(const tinyrl_t * instance);
  * instance.
  */
 extern const char *tinyrl__get_line(const tinyrl_t * instance);
-
 extern void tinyrl__set_istream(tinyrl_t * instance, FILE * istream);
-
 extern bool_t tinyrl__get_isatty(const tinyrl_t * instance);
-
 extern FILE *tinyrl__get_istream(const tinyrl_t * instance);
-
 extern FILE *tinyrl__get_ostream(const tinyrl_t * instance);
-
 extern bool_t tinyrl__get_utf8(const tinyrl_t * instance);
-
 extern void tinyrl__set_utf8(tinyrl_t * instance, bool_t utf8);
-
 extern void tinyrl__set_timeout(tinyrl_t *instance, int timeout);
 extern void tinyrl__set_timeout_fn(tinyrl_t *instance,
 	tinyrl_timeout_fn_t *fn);
-
-extern char *tinyrl_readline(tinyrl_t * instance,
-			     const char *prompt, void *context);
-
-extern char *tinyrl_forceline(tinyrl_t * instance,
-			      const char *prompt,
-			      void *context, const char *line);
-
-extern bool_t
-tinyrl_bind_key(tinyrl_t * instance, int key, tinyrl_key_func_t * fn);
+extern void tinyrl__set_keypress_fn(tinyrl_t *instance,
+	tinyrl_keypress_fn_t *fn);
+extern char *tinyrl_readline(tinyrl_t *instance,
+	const char *prompt, void *context);
+extern char *tinyrl_forceline(tinyrl_t *instance,
+	const char *prompt, void *context, const char *line);
+extern bool_t tinyrl_bind_key(tinyrl_t *instance, int key,
+	tinyrl_key_func_t *fn);
 extern void tinyrl_delete_matches(char **instance);
-extern char **tinyrl_completion(tinyrl_t * instance,
-				const char *line,
-				unsigned start,
-				unsigned end,
-				tinyrl_compentry_func_t * generator);
+extern char **tinyrl_completion(tinyrl_t *instance,
+	const char *line, unsigned start, unsigned end,
+	tinyrl_compentry_func_t *generator);
 extern void tinyrl_crlf(const tinyrl_t * instance);
 extern void tinyrl_ding(const tinyrl_t * instance);