Skip to content

Commit

Permalink
Merge pull request #277 from johalun/freebsd-tty-updates
Browse files Browse the repository at this point in the history
fd/tty: freebsd improvements
  • Loading branch information
ddevault committed Jul 26, 2017
2 parents c3a5a49 + ef3c443 commit 1d8a0ac
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
2 changes: 0 additions & 2 deletions src/session/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
62 changes: 41 additions & 21 deletions src/session/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,10 @@
#elif defined(__FreeBSD__)
# include <sys/consio.h>
# include <sys/kbio.h>
# include <termios.h>
# 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
Expand All @@ -45,6 +37,9 @@ static struct {
struct {
long kb_mode;
int vt;
#ifdef __FreeBSD__
struct termios term;
#endif
} old_state;
int tty, vt;
} wlc = {
Expand Down Expand Up @@ -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))) {
Expand All @@ -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)
Expand All @@ -126,26 +126,41 @@ 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");

// 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");
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 = {
Expand Down

0 comments on commit 1d8a0ac

Please sign in to comment.