From 19fcfcfef4854793260029e8af71dd8b7eed6b18 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sun, 27 Aug 2017 15:02:55 +0200 Subject: [PATCH] Initial support for external getty Signed-off-by: Joachim Nilsson --- src/tty.c | 94 +++++++++++++++++++++++++++++++++++++++++++------------ src/tty.h | 3 ++ 2 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/tty.c b/src/tty.c index ec63cf5c..beed0c34 100644 --- a/src/tty.c +++ b/src/tty.c @@ -83,12 +83,33 @@ void tty_sweep(void) } } -/* tty [!1-9,S] [BAUD[,BAUD,...]] [TERM] [noclear] */ +/** + * tty_register - Register a getty on a device + * @line: Configuration, text after initial "tty" + * @mtime: Modification time, to propagate to lower layers + * + * A Finit tty line can use the internal getty implementation or an + * external one, like the BusyBox getty for instance. This function + * determines which one to use based on a leading '/dev' prefix. If + * a leading '/dev' is encountered the remaining options must be in + * the following sequence: + * + * tty [!1-9,S] [BAUD[,BAUD,...]] [TERM] [noclear] + * + * Otherwise the leading prefix must be the full path to an existing + * getty implementation, with it's arguments following: + * + * tty [!1-9,S] [ARGS] + * + * Different getty implementations prefer the TTY device argument in + * different order, so take care to investigate this first. + */ int tty_register(char *line, struct timeval *mtime) { tty_node_t *entry; - int insert = 0, noclear = 0; - char *tok, *dev = NULL, *baud = NULL; + int i, num = 0, insert = 0, noclear = 0; + char *tok, *cmd = NULL, *args[10]; + char *dev = NULL, *baud = NULL; char *runlevels = NULL, *term = NULL; if (!line) { @@ -96,24 +117,45 @@ int tty_register(char *line, struct timeval *mtime) return errno = EINVAL; } - tok = strtok(line, " "); - while (tok) { - if (tok[0] == '[') - runlevels = &tok[0]; - else if (tok[0] == '/') - dev = tok; - else if (isdigit(tok[0])) - baud = tok; - else if (!strcmp(tok, "noclear")) - noclear = 1; - else - term = tok; + tok = strchr(line, '/'); + if (tok && strncmp(tok, "/dev", 4)) { + /* External getty */ + cmd = tok; - tok = strtok(NULL, " "); + tok = strtok(line, " "); + while (tok) { + if (tok[0] == '[') { + runlevels = &tok[0]; + } else if (tok[0] == '/' && tok != cmd) { + dev = strdup(tok); + args[num++] = tok; + } else { + args[num++] = tok; + } + + tok = strtok(NULL, " "); + } + } else { + /* Built-in getty */ + tok = strtok(line, " "); + while (tok) { + if (tok[0] == '[') + runlevels = &tok[0]; + else if (tok[0] == '/') + dev = strdup(tok); + else if (isdigit(tok[0])) + baud = tok; + else if (!strcmp(tok, "noclear")) + noclear = 1; + else + term = tok; + + tok = strtok(NULL, " "); + } } if (!dev) { - _e("Incomplete tty, cannot register"); + _e("Incomplete tty, no device given, cannot register."); return errno = EINVAL; } @@ -121,15 +163,24 @@ int tty_register(char *line, struct timeval *mtime) if (!entry) { insert = 1; entry = calloc(1, sizeof(*entry)); - if (!entry) + if (!entry) { + free(dev); return errno = ENOMEM; + } } - entry->data.name = strdup(dev); + entry->data.name = dev; entry->data.baud = baud ? strdup(baud) : NULL; entry->data.term = term ? strdup(term) : NULL; entry->data.noclear = noclear; entry->data.runlevels = conf_parse_runlevels(runlevels); + + /* External getty */ + entry->data.cmd = cmd; + for (i = 0; i < num; i++) + entry->data.args[i] = args[i]; + entry->data.args[++i] = NULL; + _d("Registering tty %s at %s baud with term=%s on runlevels %s", dev, baud ?: "NULL", term ?: "N/A", runlevels ?: "[2-5]"); @@ -275,7 +326,10 @@ void tty_start(finit_tty_t *tty) return; } - tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, is_console); + if (!tty->cmd) + tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, is_console); + else + tty->pid = run_getty2(dev, tty->cmd, tty->args, is_console); } void tty_stop(finit_tty_t *tty) diff --git a/src/tty.h b/src/tty.h index 9b9ed166..f2091efa 100644 --- a/src/tty.h +++ b/src/tty.h @@ -37,6 +37,9 @@ typedef struct { int noclear; int runlevels; + char *cmd; /* NULL when running built-in getty */ + char *args[10]; + int pid; } finit_tty_t;