summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-01-16 22:42:22 -0500
committerKristian Høgsberg <krh@bitplanet.net>2012-01-16 22:44:34 -0500
commit39d908e63a98a6b70a708f6693dd20a7744a6d69 (patch)
tree7852bd5625994b8d655cc8fc30a5b06c9f801eec /src
parent0bd892750d3b743a54a0645d1fde5280cbf5d12d (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.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/src/tty.c b/src/tty.c
index 7b68ff16..6fdc781a 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -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;