mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
Fix #78: Support agetty cmd line format for external getty
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -43,6 +43,27 @@ static pid_t fallback = 0;
|
||||
#endif
|
||||
static LIST_HEAD(, tty_node) tty_list = LIST_HEAD_INITIALIZER();
|
||||
|
||||
static char *canonicalize(char *tty)
|
||||
{
|
||||
struct stat st;
|
||||
static char path[80];
|
||||
|
||||
if (!tty)
|
||||
return NULL;
|
||||
|
||||
strlcpy(path, tty, sizeof(path));
|
||||
if (stat(path, &st)) {
|
||||
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, tty);
|
||||
if (stat(path, &st))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!S_ISCHR(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void tty_mark(void)
|
||||
{
|
||||
tty_node_t *tty;
|
||||
@@ -107,7 +128,8 @@ void tty_sweep(void)
|
||||
int tty_register(char *line, struct timeval *mtime)
|
||||
{
|
||||
tty_node_t *entry;
|
||||
int i, num = 1, insert = 0, noclear = 0;
|
||||
int insert = 0, noclear = 0;
|
||||
size_t i, num = 0;
|
||||
char *tok, *cmd = NULL, *args[TTY_MAX_ARGS];
|
||||
char *dev = NULL, *baud = NULL;
|
||||
char *runlevels = NULL, *term = NULL;
|
||||
@@ -116,62 +138,74 @@ int tty_register(char *line, struct timeval *mtime)
|
||||
_e("Missing argument");
|
||||
return errno = EINVAL;
|
||||
}
|
||||
fprintf(stderr, "Parsing TTY line: %s\n", line);
|
||||
|
||||
tok = strchr(line, '/');
|
||||
if (tok && strncmp(tok, "/dev", 4)) {
|
||||
/* External getty */
|
||||
cmd = tok;
|
||||
/*
|
||||
* Split line in separate arguments. For an external getty
|
||||
* this is used with execv(), for the built-in it simplifies
|
||||
* further translation.
|
||||
*/
|
||||
tok = strtok(line, " \t");
|
||||
while (tok && num < NELEMS(args)) {
|
||||
args[num++] = tok;
|
||||
tok = strtok(NULL, " \t");
|
||||
}
|
||||
|
||||
for (tok = strtok(line, " "); tok; tok = strtok(NULL, " ")) {
|
||||
if (cmd == tok) {
|
||||
cmd = strdup(tok);
|
||||
continue;
|
||||
}
|
||||
/* Iterate over all args, figure out if built-in or external */
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!dev && !cmd) {
|
||||
if (args[i][0] == '[')
|
||||
runlevels = line;
|
||||
if (!strncmp(args[i], "/dev", 4))
|
||||
dev = args[i];
|
||||
if (!strncmp(args[i], "tty", 3))
|
||||
dev = args[i];
|
||||
if (!access(args[i], X_OK))
|
||||
cmd = strdup(args[i]);
|
||||
|
||||
if (tok[0] == '[') {
|
||||
runlevels = &tok[0];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok[0] == '/' && tok != cmd)
|
||||
dev = strdup(tok);
|
||||
|
||||
args[num++] = strdup(tok);
|
||||
if (num >= TTY_MAX_ARGS)
|
||||
break;
|
||||
/* The first arg must be one of the above */
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd = strdup(cmd);
|
||||
tok = strrchr(cmd, '/');
|
||||
if (!tok)
|
||||
tok = cmd;
|
||||
else
|
||||
tok++;
|
||||
args[0] = strdup(tok);
|
||||
} 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]))
|
||||
/* Built-in getty args */
|
||||
if (dev) {
|
||||
if (isdigit(args[i][0]))
|
||||
baud = tok;
|
||||
else if (!strcmp(tok, "noclear"))
|
||||
else if (!strcmp(args[i], "noclear"))
|
||||
noclear = 1;
|
||||
else
|
||||
term = tok;
|
||||
}
|
||||
|
||||
tok = strtok(NULL, " ");
|
||||
/* External getty, figure out the device */
|
||||
if (cmd) {
|
||||
if (!strncmp(args[i], "/dev", 4)) {
|
||||
dev = args[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp(args[i], "tty", 3)) {
|
||||
dev = args[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
_e("Incomplete tty, no device given, cannot register.");
|
||||
error:
|
||||
_e("Incomplete or non-existing TTY device given, cannot register.");
|
||||
if (cmd)
|
||||
free(cmd);
|
||||
|
||||
return errno = EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure all getty (built-in + external) are registered with absolute path */
|
||||
dev = canonicalize(dev);
|
||||
if (!dev)
|
||||
goto error;
|
||||
dev = strdup(dev);
|
||||
|
||||
entry = tty_find(dev);
|
||||
if (!entry) {
|
||||
insert = 1;
|
||||
@@ -189,13 +223,24 @@ int tty_register(char *line, struct timeval *mtime)
|
||||
entry->data.runlevels = conf_parse_runlevels(runlevels);
|
||||
|
||||
/* External getty */
|
||||
entry->data.cmd = cmd;
|
||||
for (i = 0; i < num && i < TTY_MAX_ARGS; i++)
|
||||
entry->data.args[i] = args[i];
|
||||
entry->data.args[++i] = NULL;
|
||||
if (cmd) {
|
||||
int j = 0;
|
||||
|
||||
_d("Registering tty %s at %s baud with term=%s on runlevels %s",
|
||||
dev, baud ?: "NULL", term ?: "N/A", runlevels ?: "[2-5]");
|
||||
tok = strrchr(cmd, '/');
|
||||
if (!tok)
|
||||
tok = cmd;
|
||||
else
|
||||
tok++;
|
||||
entry->data.cmd = cmd;
|
||||
args[1] = strdup(tok);
|
||||
|
||||
for (i = 1; i < num; i++)
|
||||
entry->data.args[j++] = strdup(args[i]);
|
||||
entry->data.args[++j] = NULL;
|
||||
}
|
||||
|
||||
_d("Registering %s getty on TTY %s at %s baud with term %s on runlevels %s",
|
||||
cmd ? "external" : "built-in", dev, baud ?: "NULL", term ?: "N/A", runlevels ?: "[2-5]");
|
||||
|
||||
if (insert)
|
||||
LIST_INSERT_HEAD(&tty_list, entry, link);
|
||||
@@ -281,27 +326,6 @@ tty_node_t *tty_find_by_pid(pid_t pid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *canonicalize(char *tty)
|
||||
{
|
||||
struct stat st;
|
||||
static char path[80];
|
||||
|
||||
if (!tty)
|
||||
return NULL;
|
||||
|
||||
strlcpy(path, tty, sizeof(path));
|
||||
if (stat(path, &st)) {
|
||||
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, tty);
|
||||
if (stat(path, &st))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!S_ISCHR(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static int tty_exist(char *dev)
|
||||
{
|
||||
int fd;
|
||||
|
||||
Reference in New Issue
Block a user