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:
Joachim Wiberg
2021-04-14 23:41:22 +02:00
parent 0929c93caf
commit 4bb67bc06f
5 changed files with 89 additions and 36 deletions
+5 -4
View File
@@ -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
View File
@@ -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;
}
+2
View File
@@ -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;
+56 -25
View File
@@ -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);
}
/*
+1 -1
View File
@@ -45,7 +45,7 @@ struct tty {
char *tty_canonicalize (char *dev);
int tty_isatcon (char *dev);
int tty_atcon (char *buf, size_t len);
char *tty_atcon (void);
int tty_parse_args (char *cmdline, struct tty *tty);