Use a signal handler to catch SIGINT
Rather than exiting, catch SIGINT and clean up appropriately.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
diff --git a/console-server.c b/console-server.c
index 1ddb36c..3defd65 100644
--- a/console-server.c
+++ b/console-server.c
@@ -7,6 +7,8 @@
#define _GNU_SOURCE
#include <assert.h>
+#include <errno.h>
+#include <signal.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -50,6 +52,8 @@
/* we have one extra entry in the pollfds array for the VUART tty */
static const int n_internal_pollfds = 1;
+/* state shared with the signal handler */
+static bool sigint;
static void usage(const char *progname)
{
@@ -355,18 +359,38 @@
return rc;
}
+static void sighandler(int signal)
+{
+ if (signal == SIGINT)
+ sigint = true;
+}
+
int run_console(struct console *console)
{
+ sighandler_t sighandler_save;
int rc;
+ sighandler_save = signal(SIGINT, sighandler);
+
+ rc = 0;
+
for (;;) {
uint8_t buf[4096];
+ if (sigint) {
+ fprintf(stderr, "Received interrupt, exiting\n");
+ break;
+ }
+
rc = poll(console->pollfds,
console->n_pollers + n_internal_pollfds, -1);
if (rc < 0) {
- warn("poll error");
- return -1;
+ if (errno == EINTR) {
+ continue;
+ } else {
+ warn("poll error");
+ break;
+ }
}
/* process internal fd first */
@@ -376,18 +400,23 @@
rc = read(console->tty_fd, buf, sizeof(buf));
if (rc <= 0) {
warn("Error reading from tty device");
- return -1;
+ rc = -1;
+ break;
}
rc = handlers_data_in(console, buf, rc);
if (rc)
- return 0;
+ break;
}
/* ... and then the pollers */
rc = call_pollers(console);
if (rc)
- return 0;
+ break;
}
+
+ signal(SIGINT, sighandler_save);
+
+ return rc ? -1 : 0;
}
static const struct option options[] = {
{ "device", required_argument, 0, 'd'},