From 966aa112e7851625f764718e3d45c46d246760fc Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 19 Dec 2008 14:28:02 -0500 Subject: [PATCH] Ignore tty input Previously, ctrl-c would kill wayland and input like passwords and commands would get typed into the terminal under the scenes. --- wayland-system-compositor.c | 78 +++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c index d6a44111..fb44ab96 100644 --- a/wayland-system-compositor.c +++ b/wayland-system-compositor.c @@ -18,9 +18,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -74,13 +76,19 @@ struct egl_compositor { EGLContext context; EGLConfig config; struct wl_display *wl_display; - int tty_fd; int width, height, stride; struct egl_surface *background; struct wl_list input_device_list; struct wl_list surface_list; + struct wl_event_source *term_signal_source; + + /* tty handling state */ + int tty_fd; + + struct termios terminal_attributes; + struct wl_event_source *tty_input_source; struct wl_event_source *enter_vt_source; struct wl_event_source *leave_vt_source; @@ -863,11 +871,72 @@ static void on_leave_vt(int signal_number, void *data) ioctl (ec->tty_fd, VT_RELDISP, 1); } +static bool open_active_tty(struct egl_compositor *ec) +{ + ec->tty_fd = open("/dev/tty0", O_RDWR | O_NOCTTY); + + if (ec->tty_fd <= 0) { + fprintf(stderr, "failed to open active tty: %m\n"); + return FALSE; + } + return TRUE; +} + +static void +on_tty_input(int fd, uint32_t mask, void *data) +{ + struct egl_compositor *ec = data; + + /* Ignore input to tty. We get keyboard events from evdev + */ + tcflush(ec->tty_fd, TCIFLUSH); +} + +static void on_term_signal(int signal_number, void *data) +{ + struct egl_compositor *ec = data; + + if (tcsetattr(ec->tty_fd, TCSANOW, &ec->terminal_attributes) < 0) + fprintf(stderr, "could not restore terminal to canonical mode\n"); + + exit(0); +} + +static void ignore_tty_input(struct egl_compositor *ec, struct wl_event_loop *loop) +{ + struct termios raw_attributes; + + if (tcgetattr(ec->tty_fd, &ec->terminal_attributes) < 0) { + fprintf(stderr, "could not get terminal attributes: %m\n"); + return; + } + + /* Ignore control characters and disable echo + */ + raw_attributes = ec->terminal_attributes; + cfmakeraw (&raw_attributes); + + /* Fix up line endings to be normal + * (cfmakeraw hoses them) + */ + raw_attributes.c_oflag |= OPOST | OCRNL; + + if (tcsetattr(ec->tty_fd, TCSANOW, &raw_attributes) < 0) + fprintf(stderr, "could not put terminal into raw mode: %m\n"); + + ec->term_signal_source = wl_event_loop_add_signal(loop, SIGTERM, + on_term_signal, + ec); + + ec->tty_input_source = wl_event_loop_add_fd(loop, ec->tty_fd, + WL_EVENT_READABLE, + on_tty_input, ec); +} + static void watch_for_vt_changes(struct egl_compositor *ec, struct wl_event_loop *loop) { struct vt_mode mode = { 0 }; - ec->tty_fd = open("/dev/tty0", O_RDWR | O_NOCTTY); mode.mode = VT_PROCESS; mode.relsig = SIGUSR1; mode.acqsig = SIGUSR2; @@ -968,7 +1037,10 @@ egl_compositor_create(struct wl_display *display) wl_display_add_global(display, &shooter->base); loop = wl_display_get_event_loop(ec->wl_display); - watch_for_vt_changes (ec, loop); + if (open_active_tty (ec)) { + ignore_tty_input (ec, loop); + watch_for_vt_changes (ec, loop); + } ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec); ec->repaint_needed = 0; ec->repaint_on_timeout = 0;