diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-01-16 22:42:22 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-01-16 22:44:34 -0500 |
commit | 39d908e63a98a6b70a708f6693dd20a7744a6d69 (patch) | |
tree | 7852bd5625994b8d655cc8fc30a5b06c9f801eec /src | |
parent | 0bd892750d3b743a54a0645d1fde5280cbf5d12d (diff) |
tty: Open a new vt if not running on a VT
This is typically when launcing from a pty such as an X (or Wayland)
terminal or from an ssh session. Opening a new vt typically requires root
priviledges, so weston must be setuid root or laucnhed as root for this
to work.
Diffstat (limited to 'src')
-rw-r--r-- | src/tty.c | 50 |
1 files changed, 42 insertions, 8 deletions
@@ -80,6 +80,41 @@ on_tty_input(int fd, uint32_t mask, void *data) return 1; } +static int +try_open_vt(void) +{ + int tty0, vt, fd; + char filename[16]; + + tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC); + if (tty0 < 0) { + fprintf(stderr, "could not open tty0: %m\n"); + return -1; + } + + if (ioctl(tty0, VT_OPENQRY, &vt) < 0 || vt == -1) { + fprintf(stderr, "could not open tty0: %m\n"); + close(tty0); + return -1; + } + + close(tty0); + snprintf(filename, sizeof filename, "/dev/tty%d", vt); + fprintf(stderr, "compositor: using new vt %s\n", filename); + fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); + if (fd < 0) + return fd; + + if (ioctl(fd, VT_ACTIVATE, vt) < 0 || + ioctl(fd, VT_WAITACTIVE, vt) < 0) { + fprintf(stderr, "failed to swtich to new vt\n"); + close(fd); + return -1; + } + + return fd; +} + struct tty * tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func, int tty_nr) @@ -103,8 +138,14 @@ tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func, snprintf(filename, sizeof filename, "/dev/tty%d", tty_nr); fprintf(stderr, "compositor: using %s\n", filename); tty->fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); - } else { + } else if (fstat(tty->fd, &buf) == 0 && + major(buf.st_rdev) == TTY_MAJOR && + minor(buf.st_rdev) > 0) { tty->fd = fcntl(0, F_DUPFD_CLOEXEC, 0); + } else { + /* Fall back to try opening a new VT. This typically + * requires root. */ + tty->fd = try_open_vt(); } if (tty->fd <= 0) { @@ -112,13 +153,6 @@ tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func, return NULL; } - if (fstat(tty->fd, &buf) < 0 || - major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { - fprintf(stderr, "stdin not a vt (%d, %d)\n", - major(buf.st_dev), minor(buf.st_dev)); - return NULL; - } - if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) { fprintf(stderr, "could not get terminal attributes: %m\n"); return NULL; |