diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2012-09-30 19:00:45 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@googlemail.com> | 2012-09-30 19:13:02 +0200 |
commit | c43d1ca7221b8e745b61b9a3b8e71f7bf92fc244 (patch) | |
tree | 7e131799984c4406dc3d826ab45d1dd7d006927b | |
parent | c95bcdf22b1bab43b1b964b0ee0b2cea7c1c9554 (diff) |
kmscon: allow paths with --vt=<xy>
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 <dh.herrmann@googlemail.com>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/main.c | 45 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/uterm.h | 4 | ||||
-rw-r--r-- | src/uterm_vt.c | 34 | ||||
-rw-r--r-- | 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 \ @@ -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"), @@ -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 <string.h> #include <sys/ioctl.h> #include <sys/signalfd.h> +#include <sys/stat.h> #include <termios.h> #include <unistd.h> #include <xkbcommon/xkbcommon-keysyms.h> @@ -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; |