mirror of
https://github.com/troglobit/finit.git
synced 2026-10-27 12:20:54 +00: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:
1 parent
0929c93caf
commit
4bb67bc06f
5 files changed
+89
-36
No files matched your search
+5
-4
@@ -245,10 +245,6 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
|
|||||||
char name[80];
|
char name[80];
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Detach from initial controlling TTY and become session leader */
|
|
||||||
vhangup();
|
|
||||||
setsid();
|
|
||||||
|
|
||||||
fd = open(tty, O_RDWR);
|
fd = open(tty, O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
logit(LOG_ERR, "Failed opening %s: %s", tty, strerror(errno));
|
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);
|
dup2(fd, STDERR_FILENO);
|
||||||
close(fd);
|
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)
|
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0)
|
||||||
logit(LOG_WARNING, "Failed TIOCSCTTY on %s: %s", tty, strerror(errno));
|
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;
|
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))
|
if (strcmp(svc->args[i], prev))
|
||||||
diff++;
|
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 *name = NULL, *halt = NULL, *delay = NULL;
|
||||||
char *id = NULL, *env = NULL, *cgroup = NULL;
|
char *id = NULL, *env = NULL, *cgroup = NULL;
|
||||||
struct tty tty = { 0 };
|
struct tty tty = { 0 };
|
||||||
|
char *dev = NULL;
|
||||||
int levels = 0;
|
int levels = 0;
|
||||||
int manual = 0;
|
int manual = 0;
|
||||||
char *line;
|
char *line;
|
||||||
@@ -1167,7 +1172,9 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
if (tty_parse_args(cmd, &tty))
|
if (tty_parse_args(cmd, &tty))
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
len += tty.num + 5;
|
if (tty.cmd)
|
||||||
|
len += strlen(tty.cmd);
|
||||||
|
len += tty.num + 2;
|
||||||
for (i = 0; i < tty.num; i++)
|
for (i = 0; i < tty.num; i++)
|
||||||
len += strlen(tty.args[i]);
|
len += strlen(tty.args[i]);
|
||||||
|
|
||||||
@@ -1184,7 +1191,12 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
if (!cmd)
|
if (!cmd)
|
||||||
return errno;
|
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
|
} else
|
||||||
svc = svc_find(cmd, id);
|
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));
|
getcgroup(svc->group, sizeof(svc->group));
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_cmdline_args(svc, cmd);
|
|
||||||
|
|
||||||
svc->runlevels = levels;
|
svc->runlevels = levels;
|
||||||
_d("Service %s runlevel 0x%02x", svc->cmd, svc->runlevels);
|
_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) {
|
if (type == SVC_TYPE_TTY) {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
if (tty.dev)
|
if (dev)
|
||||||
strlcpy(svc->dev, tty.dev, sizeof(svc->dev));
|
strlcpy(svc->dev, dev, sizeof(svc->dev));
|
||||||
if (tty.baud)
|
if (tty.baud)
|
||||||
strlcpy(svc->baud, tty.baud, sizeof(svc->baud));
|
strlcpy(svc->baud, tty.baud, sizeof(svc->baud));
|
||||||
if (tty.term)
|
if (tty.term)
|
||||||
@@ -1261,6 +1271,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
} else
|
} else
|
||||||
parse_name(svc, name);
|
parse_name(svc, name);
|
||||||
|
|
||||||
|
parse_cmdline_args(svc, cmd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Warn if svc generates same condition (based on name:id)
|
* Warn if svc generates same condition (based on name:id)
|
||||||
* as an existing service.
|
* as an existing service.
|
||||||
@@ -1302,6 +1314,13 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
if (!file)
|
if (!file)
|
||||||
svc->protect = 1;
|
svc->protect = 1;
|
||||||
|
|
||||||
|
/* continue expanding any 'tty @console ...' */
|
||||||
|
if (tty_isatcon(tty.dev)) {
|
||||||
|
dev = tty_atcon();
|
||||||
|
if (dev)
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,8 @@ void svc_validate(svc_t *svc)
|
|||||||
for (s = svc_iterator(&iter, 1); s; s = svc_iterator(&iter, 0)) {
|
for (s = svc_iterator(&iter, 1); s; s = svc_iterator(&iter, 0)) {
|
||||||
char c[MAX_COND_LEN];
|
char c[MAX_COND_LEN];
|
||||||
|
|
||||||
|
if (s->removed)
|
||||||
|
continue;
|
||||||
if (s == svc)
|
if (s == svc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ char *tty_canonicalize(char *dev)
|
|||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (tty_isatcon(dev))
|
||||||
|
return dev;
|
||||||
|
|
||||||
strlcpy(path, dev, sizeof(path));
|
strlcpy(path, dev, sizeof(path));
|
||||||
if (stat(path, &st)) {
|
if (stat(path, &st)) {
|
||||||
@@ -76,26 +78,51 @@ int tty_isatcon(char *dev)
|
|||||||
return dev && !strcmp(dev, "@console");
|
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 (!buf) {
|
||||||
if (!fp) {
|
FILE *fp;
|
||||||
_e("Cannot find system console, is sysfs not mounted?");
|
|
||||||
errno = ENOENT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
fclose(fp);
|
||||||
return -1;
|
|
||||||
|
ptr = chomp(buf);
|
||||||
|
_d("consoles: %s", ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
chomp(buf);
|
dev = strtok_r(ptr, " \t", &save);
|
||||||
fclose(fp);
|
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;
|
tty->nologin = 1;
|
||||||
else if (!strcmp(cmd, "notty"))
|
else if (!strcmp(cmd, "notty"))
|
||||||
tty->notty = 1; /* for fallback shell */
|
tty->notty = 1; /* for fallback shell */
|
||||||
|
else if (!access(cmd, X_OK))
|
||||||
|
tty->cmd = cmd;
|
||||||
else
|
else
|
||||||
tty->args[tty->num++] = cmd;
|
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] /dev/ttyAMA0 115200 noclear vt220 # built-in
|
||||||
* tty [12345] /sbin/getty -L 115200 @console vt100 noclear # external
|
* 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"))
|
if (!strcmp(tty->args[i], "@console"))
|
||||||
dev = tty->args[i];
|
dev = tty->args[i];
|
||||||
if (!strncmp(tty->args[i], "/dev", 4))
|
if (!strncmp(tty->args[i], "/dev", 4))
|
||||||
dev = tty->args[i];
|
dev = tty->args[i];
|
||||||
if (!strncmp(tty->args[i], "tty", 3) || !strcmp(tty->args[i], "console"))
|
if (!strncmp(tty->args[i], "tty", 3) || !strcmp(tty->args[i], "console"))
|
||||||
dev = tty->args[i];
|
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 */
|
/* The first arg must be one of the above */
|
||||||
continue;
|
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) {
|
if (!tty->dev) {
|
||||||
_e("Incomplete or non-existing TTY device given, cannot register.");
|
_e("Incomplete or non-existing TTY device given, cannot register.");
|
||||||
return errno = EINVAL;
|
return errno = EINVAL;
|
||||||
@@ -214,8 +239,9 @@ static int tty_exist(char *dev)
|
|||||||
|
|
||||||
int tty_exec(svc_t *tty)
|
int tty_exec(svc_t *tty)
|
||||||
{
|
{
|
||||||
|
char *args[MAX_NUM_SVC_ARGS];
|
||||||
char *dev;
|
char *dev;
|
||||||
int rc;
|
int i, j;
|
||||||
|
|
||||||
if (tty->notty) {
|
if (tty->notty) {
|
||||||
/*
|
/*
|
||||||
@@ -247,12 +273,17 @@ int tty_exec(svc_t *tty)
|
|||||||
|
|
||||||
_d("%s: Starting %sgetty ...", dev, !tty->cmd ? "built-in " : "");
|
_d("%s: Starting %sgetty ...", dev, !tty->cmd ? "built-in " : "");
|
||||||
if (!strcmp(tty->cmd, "tty"))
|
if (!strcmp(tty->cmd, "tty"))
|
||||||
rc = run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit);
|
return 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 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct tty {
|
|||||||
char *tty_canonicalize (char *dev);
|
char *tty_canonicalize (char *dev);
|
||||||
|
|
||||||
int tty_isatcon (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);
|
int tty_parse_args (char *cmdline, struct tty *tty);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user