svn commit: r258947 - user/ed/newcons/sys/dev/vt
Aleksandr Rybalko
ray at FreeBSD.org
Thu Dec 5 00:12:53 UTC 2013
Author: ray
Date: Thu Dec 5 00:12:52 2013
New Revision: 258947
URL: http://svnweb.freebsd.org/changeset/base/258947
Log:
o Implement more standard ioctls.
o Translate old ioctls to new ones for compat with FREEBSD6/FREEBSD5/FREEBSD4.
o Fix style(9) on "return"s.
o Remove some extra debug.
Sponsored by: The FreeBSD Foundation
Modified:
user/ed/newcons/sys/dev/vt/vt_core.c
Modified: user/ed/newcons/sys/dev/vt/vt_core.c
==============================================================================
--- user/ed/newcons/sys/dev/vt/vt_core.c Wed Dec 4 21:36:17 2013 (r258946)
+++ user/ed/newcons/sys/dev/vt/vt_core.c Thu Dec 5 00:12:52 2013 (r258947)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/systm.h>
@@ -51,6 +52,11 @@ __FBSDID("$FreeBSD$");
#include <dev/kbd/kbdreg.h>
#include <dev/vt/vt.h>
+#if defined(__i386__) || defined(__amd64__)
+#include <machine/psl.h>
+#include <machine/frame.h>
+#endif
+
static tc_bell_t vtterm_bell;
static tc_cursor_t vtterm_cursor;
static tc_putchar_t vtterm_putchar;
@@ -923,7 +929,7 @@ vtterm_cngetc(struct terminal *tm)
/* Force refresh to make scrollback work. */
vt_flush(vd);
} else if (KEYFLAGS(c) == 0) {
- return KEYCHAR(c);
+ return (KEYCHAR(c));
}
if (vw->vw_kbdsq && *vw->vw_kbdsq)
@@ -1015,19 +1021,19 @@ vt_proc_alive(struct vt_window *vw)
struct proc *p;
if (vw->vw_smode.mode != VT_PROCESS)
- return FALSE;
+ return (FALSE);
if (vw->vw_proc) {
if ((p = pfind(vw->vw_pid)) != NULL)
PROC_UNLOCK(p);
if (vw->vw_proc == p)
- return TRUE;
+ return (TRUE);
vw->vw_proc = NULL;
vw->vw_smode.mode = VT_AUTO;
DPRINTF(1, "vt controlling process %d died\n", vw->vw_pid);
vw->vw_pid = 0;
}
- return FALSE;
+ return (FALSE);
}
static int
@@ -1035,18 +1041,18 @@ signal_vt_rel(struct vt_window *vw)
{
if (vw->vw_smode.mode != VT_PROCESS)
- return FALSE;
+ return (FALSE);
if (vw->vw_proc == NULL || vt_proc_alive(vw) == FALSE) {
vw->vw_proc = NULL;
vw->vw_pid = 0;
- return TRUE;
+ return (TRUE);
}
vw->vw_flags |= VWF_SWWAIT_REL;
PROC_LOCK(vw->vw_proc);
kern_psignal(vw->vw_proc, vw->vw_smode.relsig);
PROC_UNLOCK(vw->vw_proc);
DPRINTF(1, "sending relsig to %d\n", vw->vw_pid);
- return TRUE;
+ return (TRUE);
}
static int
@@ -1054,20 +1060,20 @@ signal_vt_acq(struct vt_window *vw)
{
if (vw->vw_smode.mode != VT_PROCESS)
- return FALSE;
+ return (FALSE);
if (vw == vw->vw_device->vd_windows[VT_CONSWINDOW])
cnavailable(vw->vw_terminal->consdev, FALSE);
if (vw->vw_proc == NULL || vt_proc_alive(vw) == FALSE) {
vw->vw_proc = NULL;
vw->vw_pid = 0;
- return TRUE;
+ return (TRUE);
}
vw->vw_flags |= VWF_SWWAIT_ACQ;
PROC_LOCK(vw->vw_proc);
kern_psignal(vw->vw_proc, vw->vw_smode.acqsig);
PROC_UNLOCK(vw->vw_proc);
DPRINTF(1, "sending acqsig to %d\n", vw->vw_pid);
- return TRUE;
+ return (TRUE);
}
static int
@@ -1080,9 +1086,9 @@ finish_vt_rel(struct vt_window *vw, int
callout_drain(&vw->vw_proc_dead_timer);
vt_late_window_switch(vw->vw_switch_to);
}
- return 0;
+ return (0);
}
- return EINVAL;
+ return (EINVAL);
}
static int
@@ -1091,9 +1097,9 @@ finish_vt_acq(struct vt_window *vw)
if (vw->vw_flags & VWF_SWWAIT_ACQ) {
vw->vw_flags &= ~VWF_SWWAIT_ACQ;
- return 0;
+ return (0);
}
- return EINVAL;
+ return (EINVAL);
}
void
@@ -1262,17 +1268,68 @@ vtterm_ioctl(struct terminal *tm, u_long
{
struct vt_window *vw = tm->tm_softc;
struct vt_device *vd = vw->vw_device;
- int error, s;
+ keyboard_t *kbd;
+ int error, i, s;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+ int ival;
switch (cmd) {
+ case _IO('v', 4):
+ cmd = VT_RELDISP;
+ break;
+ case _IO('v', 5):
+ cmd = VT_ACTIVATE;
+ break;
+ case _IO('v', 6):
+ cmd = VT_WAITACTIVE;
+ break;
+ case _IO('K', 20):
+ cmd = KDSKBSTATE;
+ break;
+ case _IO('K', 67):
+ cmd = KDSETRAD;
+ break;
+ case _IO('K', 7):
+ cmd = KDSKBMODE;
+ break;
+ case _IO('K', 8):
+ cmd = KDMKTONE;
+ break;
+ case _IO('K', 63):
+ cmd = KIOCSOUND;
+ break;
+ case _IO('K', 66):
+ cmd = KDSETLED;
+ break;
+ case _IO('c', 110):
+ cmd = CONS_SETKBD;
+ break;
+ }
+ ival = IOCPARM_IVAL(data);
+ data = (caddr_t)&ival;
+#endif
+
+ switch (cmd) {
+ case KDSETRAD: /* set keyboard repeat & delay rates (old) */
+ if (*(int *)data & ~0x7f)
+ return (EINVAL);
case GIO_KEYMAP:
case PIO_KEYMAP:
case GIO_DEADKEYMAP:
case PIO_DEADKEYMAP:
case GETFKEY:
case SETFKEY:
- case KDGKBINFO: {
- keyboard_t *kbd;
+ case KDGKBINFO:
+ case KDGKBTYPE:
+ case KDSKBSTATE: /* set keyboard state (locks) */
+ case KDGKBSTATE: /* get keyboard state (locks) */
+ case KDGETREPEAT: /* get keyboard repeat & delay rates */
+ case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */
+ case KDSETLED: /* set keyboard LED status */
+ case KDGETLED: /* get keyboard LED status */
+ case KBADDKBD: /* add/remove keyboard to/from mux */
+ case KBRELKBD: {
error = 0;
mtx_lock(&Giant);
@@ -1280,13 +1337,18 @@ vtterm_ioctl(struct terminal *tm, u_long
if (kbd != NULL)
error = kbdd_ioctl(kbd, cmd, data);
mtx_unlock(&Giant);
- if (error == ENOIOCTL)
- return (ENODEV);
+ if (error == ENOIOCTL) {
+ if (cmd == KDGKBTYPE) {
+ /* always return something? XXX */
+ *(int *)data = 0;
+ } else {
+ return (ENODEV);
+ }
+ }
return (error);
}
case KDGKBMODE: {
int mode = -1;
- keyboard_t *kbd;
mtx_lock(&Giant);
kbd = kbd_get_keyboard(vd->vd_keyboard);
@@ -1311,19 +1373,13 @@ vtterm_ioctl(struct terminal *tm, u_long
keyboard_t *kbd;
error = 0;
- DPRINTF(20, "%s: vd_keyboard = %d\n", __func__,
- vd->vd_keyboard);
mtx_lock(&Giant);
kbd = kbd_get_keyboard(vd->vd_keyboard);
if (kbd != NULL) {
- DPRINTF(20, "kbdd_ioctl(KDSKBMODE, %d)\n", mode);
error = kbdd_ioctl(kbd, KDSKBMODE,
(void *)&mode);
}
mtx_unlock(&Giant);
- if (error)
- DPRINTF(20, "kbdd_ioctl(KDSKBMODE) "
- "return %d\n", error);
}
return (0);
default:
@@ -1346,7 +1402,7 @@ vtterm_ioctl(struct terminal *tm, u_long
}
case CONS_GETVERS:
*(int *)data = 0x200;
- return 0;
+ return (0);
case CONS_MODEINFO:
/* XXX */
return (0);
@@ -1393,22 +1449,79 @@ vtterm_ioctl(struct terminal *tm, u_long
sm->scrmap[i] = i;
return (0);
}
- case KDGETLED:
+ case KDSETMODE:
/* XXX */
return (0);
- case KDSETLED:
- /* XXX */
+ case KDENABIO: /* allow io operations */
+ error = priv_check(td, PRIV_IO);
+ if (error != 0)
+ return (error);
+ error = securelevel_gt(td->td_ucred, 0);
+ if (error != 0)
+ return (error);
+#if defined(__i386__) || defined(__amd64__)
+ td->td_frame->tf_rflags |= PSL_IOPL;
+#endif
return (0);
- case KDSETMODE:
- /* XXX */
+ case KDDISABIO: /* disallow io operations (default) */
+#if defined(__i386__) || defined(__amd64__)
+ td->td_frame->tf_rflags &= ~PSL_IOPL;
+#endif
return (0);
- case KDSETRAD:
- /* XXX */
+ case KDMKTONE: /* sound the bell */
+ /* TODO */
return (0);
+ case KIOCSOUND: /* make tone (*data) hz */
+ /* TODO */
+ return (0);
+ case CONS_SETKBD: /* set the new keyboard */
+ mtx_lock(&Giant);
+ error = 0;
+ if (vd->vd_keyboard != *(int *)data) {
+ kbd = kbd_get_keyboard(*(int *)data);
+ if (kbd == NULL) {
+ mtx_unlock(&Giant);
+ return (EINVAL);
+ }
+ i = kbd_allocate(kbd->kb_name, kbd->kb_unit,
+ (void *)&vd->vd_keyboard, vt_kbdevent, vd);
+ if (i >= 0) {
+ if (vd->vd_keyboard != -1) {
+ kbd_release(kbd,
+ (void *)&vd->vd_keyboard);
+ }
+ kbd = kbd_get_keyboard(i);
+ vd->vd_keyboard = i;
+
+ (void)kbdd_ioctl(kbd, KDSKBMODE,
+ (caddr_t)&vd->vd_curwindow->vw_kbdmode);
+ } else {
+ error = EPERM; /* XXX */
+ }
+ }
+ mtx_unlock(&Giant);
+ return (error);
+ case CONS_RELKBD: /* release the current keyboard */
+ mtx_lock(&Giant);
+ error = 0;
+ if (vd->vd_keyboard != -1) {
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd == NULL) {
+ mtx_unlock(&Giant);
+ return (EINVAL);
+ }
+ error = kbd_release(kbd, (void *)&vd->vd_keyboard);
+ if (error == 0) {
+ vd->vd_keyboard = -1;
+ }
+ }
+ mtx_unlock(&Giant);
+ return (error);
case VT_ACTIVATE: {
int win;
win = *(int *)data - 1;
- DPRINTF(5, "%s%d: VT_ACTIVATE ttyv%d ", SC_DRIVER_NAME, VT_UNIT(vw), win);
+ DPRINTF(5, "%s%d: VT_ACTIVATE ttyv%d ", SC_DRIVER_NAME,
+ VT_UNIT(vw), win);
if ((win > VT_MAXWINDOWS) || (win < 0))
return (EINVAL);
return (vt_proc_window_switch(vd->vd_windows[win]));
@@ -1425,9 +1538,7 @@ vtterm_ioctl(struct terminal *tm, u_long
vw->vw_flags |= VWF_VTYLOCK;
else
vw->vw_flags &= ~VWF_VTYLOCK;
- case VT_OPENQRY: {
- unsigned int i;
-
+ case VT_OPENQRY:
VT_LOCK(vd);
for (i = 0; i < VT_MAXWINDOWS; i++) {
vw = vd->vd_windows[i];
@@ -1441,9 +1552,7 @@ vtterm_ioctl(struct terminal *tm, u_long
}
VT_UNLOCK(vd);
return (EINVAL);
- }
- case VT_WAITACTIVE: {
- unsigned int i;
+ case VT_WAITACTIVE:
error = 0;
i = *(unsigned int *)data;
@@ -1457,9 +1566,7 @@ vtterm_ioctl(struct terminal *tm, u_long
error = cv_wait_sig(&vd->vd_winswitch, &vd->vd_lock);
VT_UNLOCK(vd);
return (error);
- }
- case VT_SETMODE: /* set screen switcher mode */
- {
+ case VT_SETMODE: { /* set screen switcher mode */
struct vt_mode *mode;
struct proc *p1;
@@ -1508,12 +1615,11 @@ vtterm_ioctl(struct terminal *tm, u_long
return (EINVAL);
}
DPRINTF(5, "\n");
- return 0;
+ return (0);
}
-
case VT_GETMODE: /* get screen switcher mode */
bcopy(&vw->vw_smode, data, sizeof(struct vt_mode));
- return 0;
+ return (0);
case VT_RELDISP: /* screen switcher ioctl */
/*
@@ -1522,18 +1628,18 @@ vtterm_ioctl(struct terminal *tm, u_long
*/
if ((vw != vd->vd_curwindow) || (vw->vw_smode.mode !=
VT_PROCESS)) {
- return EINVAL;
+ return (EINVAL);
}
/* ...and this process is controlling it. */
if (vw->vw_proc != td->td_proc) {
- return EPERM;
+ return (EPERM);
}
error = EINVAL;
switch(*(int *)data) {
case VT_FALSE: /* user refuses to release screen, abort */
if ((error = finish_vt_rel(vw, FALSE, &s)) == 0)
- DPRINTF(5, "%s%d: VT_RELDISP: VT_FALSE\n", SC_DRIVER_NAME,
- VT_UNIT(vw));
+ DPRINTF(5, "%s%d: VT_RELDISP: VT_FALSE\n",
+ SC_DRIVER_NAME, VT_UNIT(vw));
break;
case VT_TRUE: /* user has released screen, go on */
/* finish_vt_rel(..., TRUE, ...) should not be locked */
@@ -1547,13 +1653,13 @@ vtterm_ioctl(struct terminal *tm, u_long
return (error);
case VT_ACKACQ: /* acquire acknowledged, switch completed */
if ((error = finish_vt_acq(vw)) == 0)
- DPRINTF(5, "%s%d: VT_RELDISP: VT_ACKACQ\n", SC_DRIVER_NAME,
- VT_UNIT(vw));
+ DPRINTF(5, "%s%d: VT_RELDISP: VT_ACKACQ\n",
+ SC_DRIVER_NAME, VT_UNIT(vw));
break;
default:
break;
}
- return error;
+ return (error);
}
return (ENOIOCTL);
More information about the svn-src-user
mailing list