Author: avg
Date: Wed Oct  2 13:36:54 2019
New Revision: 353005
URL: https://svnweb.freebsd.org/changeset/base/353005

Log:
  MFS12 r352896: vt: fix problems with trying to switch to a closed VT
  
  Approved by:  re (gjb)

Modified:
  releng/12.1/sys/dev/vt/vt_core.c
Directory Properties:
  releng/12.1/   (props changed)

Modified: releng/12.1/sys/dev/vt/vt_core.c
==============================================================================
--- releng/12.1/sys/dev/vt/vt_core.c    Wed Oct  2 13:30:17 2019        
(r353004)
+++ releng/12.1/sys/dev/vt/vt_core.c    Wed Oct  2 13:36:54 2019        
(r353005)
@@ -335,7 +335,7 @@ static void
 vt_switch_timer(void *arg)
 {
 
-       vt_late_window_switch((struct vt_window *)arg);
+       (void)vt_late_window_switch((struct vt_window *)arg);
 }
 
 static int
@@ -457,13 +457,22 @@ vt_window_postswitch(struct vt_window *vw)
 static int
 vt_late_window_switch(struct vt_window *vw)
 {
+       struct vt_window *curvw;
        int ret;
 
        callout_stop(&vw->vw_proc_dead_timer);
 
        ret = vt_window_switch(vw);
-       if (ret)
+       if (ret != 0) {
+               /*
+                * If the switch hasn't happened, then return the VT
+                * to the current owner, if any.
+                */
+               curvw = vw->vw_device->vd_curwindow;
+               if (curvw->vw_smode.mode == VT_PROCESS)
+                       (void)vt_window_postswitch(curvw);
                return (ret);
+       }
 
        /* Notify owner process about terminal availability. */
        if (vw->vw_smode.mode == VT_PROCESS) {
@@ -509,6 +518,19 @@ vt_proc_window_switch(struct vt_window *vw)
                return (0);     /* success */
        }
 
+       /*
+        * Early check for an attempt to switch to a non-functional VT.
+        * The same check is done in vt_window_switch(), but it's better
+        * to fail as early as possible to avoid needless pre-switch
+        * actions.
+        */
+       VT_LOCK(vd);
+       if ((vw->vw_flags & (VWF_OPENED|VWF_CONSOLE)) == 0) {
+               VT_UNLOCK(vd);
+               return (EINVAL);
+       }
+       VT_UNLOCK(vd);
+
        /* Ask current process permission to switch away. */
        if (curvw->vw_smode.mode == VT_PROCESS) {
                DPRINTF(30, "%s: VT_PROCESS ", __func__);
@@ -1792,7 +1814,7 @@ finish_vt_rel(struct vt_window *vw, int release, int *
                vw->vw_flags &= ~VWF_SWWAIT_REL;
                if (release) {
                        callout_drain(&vw->vw_proc_dead_timer);
-                       vt_late_window_switch(vw->vw_switch_to);
+                       (void)vt_late_window_switch(vw->vw_switch_to);
                }
                return (0);
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to