From c43d1ca7221b8e745b61b9a3b8e71f7bf92fc244 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 30 Sep 2012 19:00:45 +0200 Subject: [PATCH] kmscon: allow paths with --vt= The getty variants out there (including agetty) require an relative path to the /dev directory as argument. This is really odd but we want to be backwards-compatible to them so we allow this, too. --vt now accepts: * A positive number which is internally converted into /dev/ttyXY * A string that does not start with '/' or '.' which is interpreted relative to /dev as /dev/%s * Everything else is interpreted as path This option still selects only the TTY on seat0. On all other seats we do not use controlling TTYs. Signed-off-by: David Herrmann --- Makefile.am | 1 + src/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/main.h | 2 +- src/uterm.h | 4 +--- src/uterm_vt.c | 34 +++++++++++++++++++++++----------- tests/test_vt.c | 3 +-- 6 files changed, 71 insertions(+), 18 deletions(-) diff --git a/Makefile.am b/Makefile.am index e7aafda..f8215a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -415,6 +415,7 @@ endif kmscon_SOURCES = \ $(SHL_DLIST) \ + $(SHL_MISC) \ src/main.c kmscon_LDADD = \ libuterm.la \ diff --git a/src/main.c b/src/main.c index eef6454..7e1d1b4 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,7 @@ #include "log.h" #include "main.h" #include "shl_dlist.h" +#include "shl_misc.h" #include "text.h" #include "ui.h" #include "uterm.h" @@ -589,6 +590,48 @@ const struct conf_type conf_grab = { _mem, \ _def) +int conf_parse_vt(struct conf_option *opt, bool on, const char *arg) +{ + static const char prefix[] = "/dev/"; + unsigned int val; + char *str; + int ret; + + if (!shl_strtou(arg, &val)) { + ret = asprintf(&str, "%stty%u", prefix, val); + if (ret == -1) + return -ENOMEM; + } else if (*arg && *arg != '.' && *arg != '/') { + str = malloc(sizeof(prefix) + strlen(arg)); + if (!str) + return -ENOMEM; + + strcpy(str, prefix); + strcat(str, arg); + } else { + str = strdup(arg); + if (!str) + return -ENOMEM; + } + + + opt->type->free(opt); + *(void**)opt->mem = str; + return 0; +} + +void conf_default_vt(struct conf_option *opt) +{ + *(void**)opt->mem = opt->def; +} + +const struct conf_type conf_vt = { + .flags = CONF_HAS_ARG, + .parse = conf_parse_vt, + .free = conf_free_value, + .set_default = conf_default_vt, +}; + static int aftercheck_debug(struct conf_option *opt, int argc, char **argv, int idx) { @@ -679,7 +722,7 @@ struct conf_option options[] = { CONF_OPTION_UINT(0, "fps", NULL, &kmscon_conf.fps, 50), CONF_OPTION_STRING(0, "render-engine", NULL, &kmscon_conf.render_engine, NULL), CONF_OPTION_BOOL(0, "render-timing", NULL, &kmscon_conf.render_timing, false), - CONF_OPTION_INT(0, "vt", NULL, &kmscon_conf.vt, UTERM_VT_DEFAULT), + CONF_OPTION(0, 0, "vt", &conf_vt, NULL, &kmscon_conf.vt, NULL), CONF_OPTION_BOOL('s', "switchvt", NULL, &kmscon_conf.switchvt, false), CONF_OPTION_BOOL('l', "login", aftercheck_login, &kmscon_conf.login, false), CONF_OPTION_STRING('t', "term", NULL, &kmscon_conf.term, "xterm-256color"), diff --git a/src/main.h b/src/main.h index c192226..03cc549 100644 --- a/src/main.h +++ b/src/main.h @@ -47,7 +47,7 @@ struct kmscon_conf_t { /* disable notices and warnings */ bool silent; /* VT number to run on on seat0 */ - int vt; + char *vt; /* enter new VT directly */ bool switchvt; /* use framebuffers instead of DRM */ diff --git a/src/uterm.h b/src/uterm.h index 3359c39..98232ad 100644 --- a/src/uterm.h +++ b/src/uterm.h @@ -334,8 +334,6 @@ enum uterm_vt_mode { UTERM_VT_DEAD, }; -#define UTERM_VT_DEFAULT (-1) - typedef int (*uterm_vt_cb) (struct uterm_vt *vt, unsigned int action, void *data); @@ -346,7 +344,7 @@ void uterm_vt_master_unref(struct uterm_vt_master *vtm); int uterm_vt_allocate(struct uterm_vt_master *vt, struct uterm_vt **out, const char *seat, struct uterm_input *input, - int vt_for_seat0, uterm_vt_cb cb, void *data); + const char *vt_for_seat0, uterm_vt_cb cb, void *data); void uterm_vt_deallocate(struct uterm_vt *vt); void uterm_vt_ref(struct uterm_vt *vt); void uterm_vt_unref(struct uterm_vt *vt); diff --git a/src/uterm_vt.c b/src/uterm_vt.c index d7e11a7..8f713af 100644 --- a/src/uterm_vt.c +++ b/src/uterm_vt.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -159,15 +160,16 @@ static void real_input(struct ev_fd *fd, int mask, void *data) tcflush(vt->real_fd, TCIFLUSH); } -static int open_tty(int id, int *tty_fd, int *tty_num) +static int open_tty(const char *dev, int *tty_fd, int *tty_num) { - int fd, err1; + int fd, err1, id, ret; char filename[16]; + struct stat st; if (!tty_fd || !tty_num) return -EINVAL; - if (id < 0) { + if (!dev) { fd = open("/dev/tty0", O_NONBLOCK | O_NOCTTY | O_CLOEXEC); if (fd < 0) { err1 = errno; @@ -186,24 +188,34 @@ static int open_tty(int id, int *tty_fd, int *tty_num) return -EINVAL; } close(fd); + + snprintf(filename, sizeof(filename), "/dev/tty%d", id); + filename[sizeof(filename) - 1] = 0; + dev = filename; } - snprintf(filename, sizeof(filename), "/dev/tty%d", id); - filename[sizeof(filename) - 1] = 0; - log_notice("using tty %s", filename); + log_notice("using tty %s", dev); - fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); + fd = open(dev, O_RDWR | O_NOCTTY | O_CLOEXEC); if (fd < 0) { - log_err("cannot open tty %s", filename); + log_err("cannot open tty %s", dev); return -errno; } + ret = fstat(fd, &st); + if (ret) { + log_error("cannot introspect tty %s (%d): %m", dev, errno); + close(fd); + return -errno; + } + id = minor(st.st_rdev); + *tty_fd = fd; *tty_num = id; return 0; } -static int real_open(struct uterm_vt *vt, int vt_for_seat0) +static int real_open(struct uterm_vt *vt, const char *vt_for_seat0) { struct termios raw_attribs; struct vt_mode mode; @@ -251,7 +263,7 @@ static int real_open(struct uterm_vt *vt, int vt_for_seat0) log_warn("cannot put terminal into raw mode"); if (ioctl(vt->real_fd, KDSETMODE, KD_GRAPHICS)) { - log_err("vt: cannot set graphics mode\n"); + log_err("vt: cannot set graphics mode"); ret = -errno; goto err_reset; } @@ -455,7 +467,7 @@ int uterm_vt_allocate(struct uterm_vt_master *vtm, struct uterm_vt **out, const char *seat, struct uterm_input *input, - int vt_for_seat0, + const char *vt_for_seat0, uterm_vt_cb cb, void *data) { diff --git a/tests/test_vt.c b/tests/test_vt.c index bc3e235..9ce7bd0 100644 --- a/tests/test_vt.c +++ b/tests/test_vt.c @@ -102,8 +102,7 @@ int main(int argc, char **argv) if (ret) goto err_exit; - ret = uterm_vt_allocate(vtm, &vt, NULL, NULL, UTERM_VT_DEFAULT, NULL, - NULL); + ret = uterm_vt_allocate(vtm, &vt, NULL, NULL, NULL, NULL, NULL); if (ret) goto err_vtm;