mirror of
https://github.com/troglobit/finit.git
synced 2026-10-31 13:00:32 +00:00
Fix #78: Support agetty cmd line format for external getty
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
513f03b897
commit
dec21e758a
1 file changed
+91
-67
@@ -43,6 +43,27 @@ static pid_t fallback = 0;
|
|||||||
#endif
|
#endif
|
||||||
static LIST_HEAD(, tty_node) tty_list = LIST_HEAD_INITIALIZER();
|
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)
|
void tty_mark(void)
|
||||||
{
|
{
|
||||||
tty_node_t *tty;
|
tty_node_t *tty;
|
||||||
@@ -107,7 +128,8 @@ void tty_sweep(void)
|
|||||||
int tty_register(char *line, struct timeval *mtime)
|
int tty_register(char *line, struct timeval *mtime)
|
||||||
{
|
{
|
||||||
tty_node_t *entry;
|
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 *tok, *cmd = NULL, *args[TTY_MAX_ARGS];
|
||||||
char *dev = NULL, *baud = NULL;
|
char *dev = NULL, *baud = NULL;
|
||||||
char *runlevels = NULL, *term = NULL;
|
char *runlevels = NULL, *term = NULL;
|
||||||
@@ -116,62 +138,74 @@ int tty_register(char *line, struct timeval *mtime)
|
|||||||
_e("Missing argument");
|
_e("Missing argument");
|
||||||
return errno = EINVAL;
|
return errno = EINVAL;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "Parsing TTY line: %s\n", line);
|
||||||
|
|
||||||
tok = strchr(line, '/');
|
/*
|
||||||
if (tok && strncmp(tok, "/dev", 4)) {
|
* Split line in separate arguments. For an external getty
|
||||||
/* External getty */
|
* this is used with execv(), for the built-in it simplifies
|
||||||
cmd = tok;
|
* 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, " ")) {
|
/* Iterate over all args, figure out if built-in or external */
|
||||||
if (cmd == tok) {
|
for (i = 0; i < num; i++) {
|
||||||
cmd = strdup(tok);
|
if (!dev && !cmd) {
|
||||||
continue;
|
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] == '[') {
|
/* The first arg must be one of the above */
|
||||||
runlevels = &tok[0];
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tok[0] == '/' && tok != cmd)
|
|
||||||
dev = strdup(tok);
|
|
||||||
|
|
||||||
args[num++] = strdup(tok);
|
|
||||||
if (num >= TTY_MAX_ARGS)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = strdup(cmd);
|
/* Built-in getty args */
|
||||||
tok = strrchr(cmd, '/');
|
if (dev) {
|
||||||
if (!tok)
|
if (isdigit(args[i][0]))
|
||||||
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]))
|
|
||||||
baud = tok;
|
baud = tok;
|
||||||
else if (!strcmp(tok, "noclear"))
|
else if (!strcmp(args[i], "noclear"))
|
||||||
noclear = 1;
|
noclear = 1;
|
||||||
else
|
else
|
||||||
term = tok;
|
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) {
|
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;
|
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);
|
entry = tty_find(dev);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
insert = 1;
|
insert = 1;
|
||||||
@@ -189,13 +223,24 @@ int tty_register(char *line, struct timeval *mtime)
|
|||||||
entry->data.runlevels = conf_parse_runlevels(runlevels);
|
entry->data.runlevels = conf_parse_runlevels(runlevels);
|
||||||
|
|
||||||
/* External getty */
|
/* External getty */
|
||||||
entry->data.cmd = cmd;
|
if (cmd) {
|
||||||
for (i = 0; i < num && i < TTY_MAX_ARGS; i++)
|
int j = 0;
|
||||||
entry->data.args[i] = args[i];
|
|
||||||
entry->data.args[++i] = NULL;
|
|
||||||
|
|
||||||
_d("Registering tty %s at %s baud with term=%s on runlevels %s",
|
tok = strrchr(cmd, '/');
|
||||||
dev, baud ?: "NULL", term ?: "N/A", runlevels ?: "[2-5]");
|
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)
|
if (insert)
|
||||||
LIST_INSERT_HEAD(&tty_list, entry, link);
|
LIST_INSERT_HEAD(&tty_list, entry, link);
|
||||||
@@ -281,27 +326,6 @@ tty_node_t *tty_find_by_pid(pid_t pid)
|
|||||||
return NULL;
|
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)
|
static int tty_exist(char *dev)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|||||||
Reference in new issue
Block a user