mirror of
https://github.com/troglobit/finit.git
synced 2026-10-05 07:13:44 +07:00
Restore @console handling and support for external getty
- Drop vhangup(), how did things ever work *with* this in?! - setsid() + TIOCSCTTY are best buds, see notty code - Allow storing any non-NULL string as tty->dev, expand in service_register() - Reorder parse_cmdline_args(), we need to expand @console to current dev - Fix tty arg parser, swapparoo for external getty - Refactor tty_atcon(), iterated over by service_register() - New arg format, need to translate for old run_getty2() Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
+5
-4
@@ -245,10 +245,6 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
|
||||
char name[80];
|
||||
int fd;
|
||||
|
||||
/* Detach from initial controlling TTY and become session leader */
|
||||
vhangup();
|
||||
setsid();
|
||||
|
||||
fd = open(tty, O_RDWR);
|
||||
if (fd < 0) {
|
||||
logit(LOG_ERR, "Failed opening %s: %s", tty, strerror(errno));
|
||||
@@ -260,6 +256,11 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
|
||||
dup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* Become session leader and set controlling TTY
|
||||
* to enable Ctrl-C and job control in shell.
|
||||
*/
|
||||
setsid();
|
||||
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0)
|
||||
logit(LOG_WARNING, "Failed TIOCSCTTY on %s: %s", tty, strerror(errno));
|
||||
|
||||
|
||||
+25
-6
@@ -988,6 +988,10 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* replace any @console arg with the expanded device name */
|
||||
if (svc_is_tty(svc) && tty_isatcon(svc->args[i]))
|
||||
strlcpy(svc->args[i], svc->dev, sizeof(svc->args[i]));
|
||||
|
||||
if (strcmp(svc->args[i], prev))
|
||||
diff++;
|
||||
|
||||
@@ -1074,6 +1078,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
char *name = NULL, *halt = NULL, *delay = NULL;
|
||||
char *id = NULL, *env = NULL, *cgroup = NULL;
|
||||
struct tty tty = { 0 };
|
||||
char *dev = NULL;
|
||||
int levels = 0;
|
||||
int manual = 0;
|
||||
char *line;
|
||||
@@ -1167,7 +1172,9 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
if (tty_parse_args(cmd, &tty))
|
||||
return errno;
|
||||
|
||||
len += tty.num + 5;
|
||||
if (tty.cmd)
|
||||
len += strlen(tty.cmd);
|
||||
len += tty.num + 2;
|
||||
for (i = 0; i < tty.num; i++)
|
||||
len += strlen(tty.args[i]);
|
||||
|
||||
@@ -1184,7 +1191,12 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
if (!cmd)
|
||||
return errno;
|
||||
|
||||
svc = svc_find_by_tty(tty.dev);
|
||||
if (tty_isatcon(tty.dev))
|
||||
dev = tty_atcon();
|
||||
else
|
||||
dev = tty.dev;
|
||||
next:
|
||||
svc = svc_find_by_tty(dev);
|
||||
} else
|
||||
svc = svc_find(cmd, id);
|
||||
|
||||
@@ -1222,8 +1234,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
getcgroup(svc->group, sizeof(svc->group));
|
||||
}
|
||||
|
||||
parse_cmdline_args(svc, cmd);
|
||||
|
||||
svc->runlevels = levels;
|
||||
_d("Service %s runlevel 0x%02x", svc->cmd, svc->runlevels);
|
||||
|
||||
@@ -1232,8 +1242,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
if (type == SVC_TYPE_TTY) {
|
||||
char *ptr;
|
||||
|
||||
if (tty.dev)
|
||||
strlcpy(svc->dev, tty.dev, sizeof(svc->dev));
|
||||
if (dev)
|
||||
strlcpy(svc->dev, dev, sizeof(svc->dev));
|
||||
if (tty.baud)
|
||||
strlcpy(svc->baud, tty.baud, sizeof(svc->baud));
|
||||
if (tty.term)
|
||||
@@ -1261,6 +1271,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
} else
|
||||
parse_name(svc, name);
|
||||
|
||||
parse_cmdline_args(svc, cmd);
|
||||
|
||||
/*
|
||||
* Warn if svc generates same condition (based on name:id)
|
||||
* as an existing service.
|
||||
@@ -1302,6 +1314,13 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
if (!file)
|
||||
svc->protect = 1;
|
||||
|
||||
/* continue expanding any 'tty @console ...' */
|
||||
if (tty_isatcon(tty.dev)) {
|
||||
dev = tty_atcon();
|
||||
if (dev)
|
||||
goto next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,8 @@ void svc_validate(svc_t *svc)
|
||||
for (s = svc_iterator(&iter, 1); s; s = svc_iterator(&iter, 0)) {
|
||||
char c[MAX_COND_LEN];
|
||||
|
||||
if (s->removed)
|
||||
continue;
|
||||
if (s == svc)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ char *tty_canonicalize(char *dev)
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
if (tty_isatcon(dev))
|
||||
return dev;
|
||||
|
||||
strlcpy(path, dev, sizeof(path));
|
||||
if (stat(path, &st)) {
|
||||
@@ -76,26 +78,51 @@ int tty_isatcon(char *dev)
|
||||
return dev && !strcmp(dev, "@console");
|
||||
}
|
||||
|
||||
int tty_atcon(char *buf, size_t len)
|
||||
/*
|
||||
* Returns console TTYs known by the kernel, from cmdline
|
||||
*/
|
||||
char *tty_atcon(void)
|
||||
{
|
||||
FILE *fp;
|
||||
static char *buf = NULL;
|
||||
static char *save;
|
||||
char *ptr = NULL;
|
||||
char *dev;
|
||||
|
||||
fp = fopen("/sys/class/tty/console/active", "r");
|
||||
if (!fp) {
|
||||
_e("Cannot find system console, is sysfs not mounted?");
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
if (!buf) {
|
||||
FILE *fp;
|
||||
|
||||
if (!fgets(buf, len, fp)) {
|
||||
fp = fopen("/sys/class/tty/console/active", "r");
|
||||
if (!fp) {
|
||||
_e("Cannot find system console, is sysfs not mounted?");
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = malloc(512);
|
||||
if (!buf) {
|
||||
_pe("Failed allocating memory for @console");
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!fgets(buf, 512, fp)) {
|
||||
fclose(fp);
|
||||
goto done;
|
||||
}
|
||||
fclose(fp);
|
||||
return -1;
|
||||
|
||||
ptr = chomp(buf);
|
||||
_d("consoles: %s", ptr);
|
||||
}
|
||||
|
||||
chomp(buf);
|
||||
fclose(fp);
|
||||
dev = strtok_r(ptr, " \t", &save);
|
||||
if (!dev) {
|
||||
done:
|
||||
free(buf);
|
||||
return buf = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +160,8 @@ int tty_parse_args(char *cmd, struct tty *tty)
|
||||
tty->nologin = 1;
|
||||
else if (!strcmp(cmd, "notty"))
|
||||
tty->notty = 1; /* for fallback shell */
|
||||
else if (!access(cmd, X_OK))
|
||||
tty->cmd = cmd;
|
||||
else
|
||||
tty->args[tty->num++] = cmd;
|
||||
|
||||
@@ -151,15 +180,13 @@ int tty_parse_args(char *cmd, struct tty *tty)
|
||||
* tty [12345] /dev/ttyAMA0 115200 noclear vt220 # built-in
|
||||
* tty [12345] /sbin/getty -L 115200 @console vt100 noclear # external
|
||||
*/
|
||||
if ((!tty->cmd && !dev) || (tty->cmd && !dev)) {
|
||||
if (!dev) {
|
||||
if (!strcmp(tty->args[i], "@console"))
|
||||
dev = tty->args[i];
|
||||
if (!strncmp(tty->args[i], "/dev", 4))
|
||||
dev = tty->args[i];
|
||||
if (!strncmp(tty->args[i], "tty", 3) || !strcmp(tty->args[i], "console"))
|
||||
dev = tty->args[i];
|
||||
if (!access(tty->args[i], X_OK))
|
||||
tty->cmd = tty->args[i];
|
||||
|
||||
/* The first arg must be one of the above */
|
||||
continue;
|
||||
@@ -182,9 +209,7 @@ int tty_parse_args(char *cmd, struct tty *tty)
|
||||
}
|
||||
}
|
||||
|
||||
if (!tty_isatcon(dev))
|
||||
tty->dev = tty_canonicalize(dev);
|
||||
|
||||
tty->dev = tty_canonicalize(dev);
|
||||
if (!tty->dev) {
|
||||
_e("Incomplete or non-existing TTY device given, cannot register.");
|
||||
return errno = EINVAL;
|
||||
@@ -214,8 +239,9 @@ static int tty_exist(char *dev)
|
||||
|
||||
int tty_exec(svc_t *tty)
|
||||
{
|
||||
char *args[MAX_NUM_SVC_ARGS];
|
||||
char *dev;
|
||||
int rc;
|
||||
int i, j;
|
||||
|
||||
if (tty->notty) {
|
||||
/*
|
||||
@@ -247,12 +273,17 @@ int tty_exec(svc_t *tty)
|
||||
|
||||
_d("%s: Starting %sgetty ...", dev, !tty->cmd ? "built-in " : "");
|
||||
if (!strcmp(tty->cmd, "tty"))
|
||||
rc = run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit);
|
||||
else
|
||||
// rc = run_getty2(dev, tty->cmd, tty->args, tty->noclear, tty->nowait, tty->rlimit);
|
||||
rc = -1;
|
||||
return run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit);
|
||||
|
||||
return rc;
|
||||
for (i = 1, j = 0; i < MAX_NUM_SVC_ARGS; i++) {
|
||||
if (!tty->args[i][0])
|
||||
break;
|
||||
|
||||
args[j++] = tty->args[i];
|
||||
}
|
||||
args[j++] = NULL;
|
||||
|
||||
return run_getty2(dev, tty->cmd, args, tty->noclear, tty->nowait, tty->rlimit);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user