diff --git a/src/session/fd.c b/src/session/fd.c index 09c3468a..6cbb55ba 100644 --- a/src/session/fd.c +++ b/src/session/fd.c @@ -185,9 +185,7 @@ fd_open(const char *path, int flags, enum wlc_fd_type type) FILTER("/dev/dri/card", DRM_MAJOR), // WLC_FD_DRM }; #undef FILTER -#endif -#ifdef __linux__ if (type > WLC_FD_LAST || memcmp(path, allow[type].base, allow[type].size)) { wlc_log(WLC_LOG_WARN, "Denying open from: %s", path); return -1; diff --git a/src/session/tty.c b/src/session/tty.c index 56f94c81..c7243b23 100644 --- a/src/session/tty.c +++ b/src/session/tty.c @@ -19,18 +19,10 @@ #elif defined(__FreeBSD__) # include # include +# include # define TTY_BASENAME "/dev/ttyv" # define TTY_0 "/dev/ttyv0" # define TTY_MAJOR 0 -# define VT_GETSTATE 0x5603 -# define VT_ACTIVATE 0x5606 -# define K_UNICODE 0x03 -# define K_OFF 0x04 -struct vt_stat { - unsigned short v_active; /* active vt */ - unsigned short v_signal; /* signal to send */ - unsigned short v_state; /* vt bitmask */ -}; #endif #ifndef KDSKBMUTE @@ -45,6 +37,9 @@ static struct { struct { long kb_mode; int vt; +#ifdef __FreeBSD__ + struct termios term; +#endif } old_state; int tty, vt; } wlc = { @@ -84,7 +79,12 @@ static int open_tty(int vt) { char tty_name[64]; +#if defined(__FreeBSD__) + // /dev/ttyvX index is zero-based, vt index starts from 1... + snprintf(tty_name, sizeof tty_name, "%s%d", TTY_BASENAME, vt-1); +#else snprintf(tty_name, sizeof tty_name, "%s%d", TTY_BASENAME, vt); +#endif /* check if we are running on the desired vt */ if (ttyname(STDIN_FILENO) && chck_cstreq(tty_name, ttyname(STDIN_FILENO))) { @@ -101,22 +101,22 @@ open_tty(int vt) } static bool -setup_tty(int fd, bool replace_vt) +setup_tty(int fd, int vt, bool replace_vt) { if (fd < 0) return false; +#if defined(__FreeBSD__) + wlc.vt = vt; +#else struct stat st; if (fstat(fd, &st) == -1) die("Could not stat tty fd"); - wlc.vt = minor(st.st_rdev); - if (major(st.st_rdev) != TTY_MAJOR || wlc.vt == 0) die("Not a valid vt"); +#endif -/* FreeBSD's new vt is still missing some bits */ -#if defined(__linux__) if (!replace_vt) { int kd_mode; if (ioctl(fd, KDGETMODE, &kd_mode) == -1) @@ -126,18 +126,20 @@ setup_tty(int fd, bool replace_vt) die("vt%d is already in graphics mode (%d). Is another display server running?", wlc.vt, kd_mode); } +#if defined(__FreeBSD__) + ioctl(fd, VT_GETACTIVE, &wlc.old_state.vt); +#else struct vt_stat state; if (ioctl(fd, VT_GETSTATE, &state) == -1) die("Could not get current vt"); - wlc.old_state.vt = state.v_active; +#endif if (ioctl(fd, VT_ACTIVATE, wlc.vt) == -1) die("Could not activate vt%d", wlc.vt); if (ioctl(fd, VT_WAITACTIVE, wlc.vt) == -1) die("Could not wait for vt%d to become active", wlc.vt); -#endif if (ioctl(fd, KDGKBMODE, &wlc.old_state.kb_mode) == -1) die("Could not get keyboard mode"); @@ -145,7 +147,20 @@ setup_tty(int fd, bool replace_vt) // vt will be restored from now on wlc.tty = fd; -#if defined(__linux__) +#if defined(__FreeBSD__) + if (ioctl(fd, KDSKBMODE, K_CODE) == -1) { + wlc_tty_terminate(); + die("Could not set keyboard mode to K_CODE"); + } + /* Put the tty into raw mode */ + struct termios tios; + if (tcgetattr(fd, &tios)) + die("Failed to get terminal attribute"); + memcpy(&wlc.old_state.term, &tios, sizeof(tios)); + cfmakeraw(&tios); + if (tcsetattr(fd, TCSANOW, &tios)) + die("Failed to set terminal attribute"); +#else if (ioctl(fd, KDSKBMUTE, 1) == -1 && ioctl(fd, KDSKBMODE, K_OFF) == -1) { wlc_tty_terminate(); die("Could not set keyboard mode to K_OFF"); @@ -157,18 +172,19 @@ setup_tty(int fd, bool replace_vt) die("Could not set console mode to KD_GRAPHICS"); } -#if defined(__linux__) struct vt_mode mode = { .mode = VT_PROCESS, .relsig = SIGUSR1, - .acqsig = SIGUSR2 + .acqsig = SIGUSR2, +#if defined(__FreeBSD__) + .frsig = SIGIO, /* not used, but has to be set anyway */ +#endif }; if (ioctl(fd, VT_SETMODE, &mode) == -1) { wlc_tty_terminate(); die("Could not set vt%d mode", wlc.vt); } -#endif return true; } @@ -234,9 +250,13 @@ wlc_tty_terminate(void) if (ioctl(wlc.tty, VT_ACTIVATE, wlc.vt) != -1 && ioctl(wlc.tty, VT_WAITACTIVE, wlc.vt) != -1) { wlc_log(WLC_LOG_INFO, "Restoring vt %d (0x%lx) (fd %d)", wlc.vt, wlc.old_state.kb_mode, wlc.tty); +#if defined(__FreeBSD__) + if (ioctl(wlc.tty, KDSKBMODE, wlc.old_state.kb_mode) == -1) +#else if (ioctl(wlc.tty, KDSKBMUTE, 0) == -1 && ioctl(wlc.tty, KDSKBMODE, wlc.old_state.kb_mode) == -1 && ioctl(wlc.tty, KDSKBMODE, K_UNICODE) == -1) +#endif wlc_log(WLC_LOG_ERROR, "Failed to restore vt%d KDSKBMODE", wlc.vt); if (ioctl(wlc.tty, KDSETMODE, KD_TEXT) == -1) @@ -272,7 +292,7 @@ wlc_tty_init(int vt) if (!vt && !(vt = find_vt(getenv("XDG_VTNR"), &replace_vt))) die("Could not find vt"); - if (!setup_tty(open_tty(vt), replace_vt)) + if (!setup_tty(open_tty(vt), vt, replace_vt)) die("Could not open tty with vt%d", vt); struct sigaction action = {