summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-09-30 19:00:45 +0200
committerDavid Herrmann <dh.herrmann@googlemail.com>2012-09-30 19:13:02 +0200
commitc43d1ca7221b8e745b61b9a3b8e71f7bf92fc244 (patch)
tree7e131799984c4406dc3d826ab45d1dd7d006927b
parentc95bcdf22b1bab43b1b964b0ee0b2cea7c1c9554 (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.am1
-rw-r--r--src/main.c45
-rw-r--r--src/main.h2
-rw-r--r--src/uterm.h4
-rw-r--r--src/uterm_vt.c34
-rw-r--r--tests/test_vt.c3
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 <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;