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.
This commit is contained in:
parent
0bd892750d
commit
39d908e63a
50
src/tty.c
50
src/tty.c
@ -80,6 +80,41 @@ on_tty_input(int fd, uint32_t mask, void *data)
|
|||||||
return 1;
|
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 *
|
struct tty *
|
||||||
tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func,
|
tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func,
|
||||||
int tty_nr)
|
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);
|
snprintf(filename, sizeof filename, "/dev/tty%d", tty_nr);
|
||||||
fprintf(stderr, "compositor: using %s\n", filename);
|
fprintf(stderr, "compositor: using %s\n", filename);
|
||||||
tty->fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
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);
|
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) {
|
if (tty->fd <= 0) {
|
||||||
@ -112,13 +153,6 @@ tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func,
|
|||||||
return NULL;
|
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) {
|
if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) {
|
||||||
fprintf(stderr, "could not get terminal attributes: %m\n");
|
fprintf(stderr, "could not get terminal attributes: %m\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user