replace old SIGINT handling with SIGTERM, and have SIGINT just abort the console input line. Now EOF (^D) will cause lua_console to nexus_shutdown
--- a/src/console.c Mon May 04 20:55:43 2009 +0300
+++ b/src/console.c Mon May 04 23:19:50 2009 +0300
@@ -7,6 +7,7 @@
#include <readline/readline.h>
#include <readline/history.h>
+#include <signal.h>
#include <assert.h>
/** The global console state */
@@ -35,9 +36,19 @@
static void console_line (char *line)
{
struct console *console = &_console;
+
+ // special-case EOF
+ if (!line) {
+ // prettify
+ rl_crlf();
+ rl_on_new_line();
- // XXX: line == NULL -> EOF?
-
+ if (console->callbacks->on_eof)
+ console->callbacks->on_eof(console->cb_arg);
+
+ return;
+ }
+
// update state
console->have_input = false;
@@ -55,6 +66,20 @@
console->have_input = true;
}
+static void on_sigint (int sig)
+{
+ struct console *console = &_console;
+
+ (void) sig;
+
+ // interrupt the input line
+ rl_free_line_state();
+
+ // redisplay on new line
+ rl_crlf();
+ rl_callback_handler_install(console->config.prompt, console_line);
+}
+
err_t console_init (struct console **console_ptr, struct event_base *ev_base, const struct console_config *config,
const struct console_callbacks *callbacks, void *cb_arg, struct error_info *err)
{
@@ -63,6 +88,9 @@
// check it's not already initialized
assert(!console->initialized);
+ // store
+ console->config = *config;
+
// store callbacks?
if (callbacks)
console_set_callbacks(console, callbacks, cb_arg);
@@ -70,9 +98,16 @@
// setup the input event
if ((console->ev = event_new(ev_base, STDIN_FILENO, EV_READ | EV_PERSIST, &console_input, console)) == NULL)
JUMP_SET_ERROR(err, ERR_EVENT_NEW);
+
+ // set our SIGINT handler
+ struct sigaction sigact;
+
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_handler = on_sigint;
+ sigaction(SIGINT, &sigact, NULL);
// setup readline
- rl_callback_handler_install(config->prompt, &console_line);
+ rl_callback_handler_install(config->prompt, console_line);
// mark it as initialized
console->initialized = true;
--- a/src/console.h Mon May 04 20:55:43 2009 +0300
+++ b/src/console.h Mon May 04 23:19:50 2009 +0300
@@ -21,10 +21,15 @@
struct console_callbacks {
/**
* A line was read from the console.
- *
- * XXX: currently, line might be NULL on EOF, but this is probably a second callback
*/
void (*on_line) (const char *line, void *arg);
+
+ /**
+ * EOF was read on the console.
+ *
+ * Note that for interactive consoles, EOF isn't actually EOF - there might be multiple EOFs...
+ */
+ void (*on_eof) (void *arg);
};
/**
@@ -41,13 +46,16 @@
* You may replace the callbacks/cb_arg field with a new one at any time, using console_set_callbacks().
*/
struct console {
- /** The input event */
+ /** Configuration */
+ struct console_config config;
+
+ /** Input event */
struct event *ev;
- /** The callback functions */
+ /** Callback functions */
const struct console_callbacks *callbacks;
- /** The callback context argument */
+ /** Callback context argument */
void *cb_arg;
/** Already initialized? */
--- a/src/lua_console.c Mon May 04 20:55:43 2009 +0300
+++ b/src/lua_console.c Mon May 04 23:19:50 2009 +0300
@@ -23,8 +23,17 @@
}
+static void lua_console_on_eof (void *arg)
+{
+ struct lua_console *lc = arg;
+
+ // exit the process
+ nexus_shutdown(lc->lua->nexus);
+}
+
static struct console_callbacks _console_callbacks = {
- .on_line = &lua_console_on_line,
+ .on_line = lua_console_on_line,
+ .on_eof = lua_console_on_eof,
};
err_t lua_console_create (struct lua_console **lc_ptr, struct console *console, struct nexus_lua *lua, struct error_info *err)
--- a/src/nexus.c Mon May 04 20:55:43 2009 +0300
+++ b/src/nexus.c Mon May 04 23:19:50 2009 +0300
@@ -495,17 +495,25 @@
memset(nexus, 0, sizeof(*nexus));
}
-static void on_sigint (evutil_socket_t sig, short what, void *arg)
+static void on_sigterm (evutil_socket_t sig, short what, void *arg)
{
struct nexus *nexus = arg;
(void) sig;
(void) what;
- log_info("Quitting...");
-
- // shutdown
- nexus_shutdown(nexus);
+ if (!nexus->shutdown) {
+ // shutdown
+ log_info("Terminating...");
+
+ nexus_shutdown(nexus);
+
+ } else {
+ // already tried to shutdown
+ log_info("Crashing!");
+
+ nexus_crash(nexus);
+ }
}
int main (int argc, char **argv)
@@ -527,11 +535,11 @@
// add our signal handlers
if (signal_ignore(SIGPIPE, &err))
- FATAL_ERROR(&err, "signals_ignore(SIGPIPE)");
+ FATAL_ERROR(&err, "signals_ignore");
- // XXX: add our SIGINT handler after console_init()?
- if ((ERROR_CODE(&err) = signals_add(nexus->signals, SIGINT, &on_sigint, nexus)))
- FATAL_ERROR(&err, "signals_add(SIGINT)");
+ // add our SIGTERM handler before console_init()?
+ if ((ERROR_CODE(&err) = signals_add(nexus->signals, SIGTERM, on_sigterm, nexus)))
+ FATAL_ERROR(&err, "signals_add");
// initialize sock module
@@ -567,6 +575,8 @@
FATAL("event_base_dispatch returned without shutdown");
}
+ } else {
+ log_warn("zero return from event_base_dispatch");
}
// cleanup