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>
This commit is contained in:
David Herrmann 2012-09-30 19:00:45 +02:00
parent c95bcdf22b
commit c43d1ca722
6 changed files with 71 additions and 18 deletions

View File

@ -415,6 +415,7 @@ endif
kmscon_SOURCES = \
$(SHL_DLIST) \
$(SHL_MISC) \
src/main.c
kmscon_LDADD = \
libuterm.la \

View File

@ -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"),

View File

@ -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 */

View File

@ -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);

View File

@ -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)
{

View File

@ -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;