Package: console-tools
Version: 1:0.2.3dbs-62
Severity: normal
Tags: patch

According to a comment in the kbd source, Linux 2.6.1 fixed the UNIMAP
ioctls to be per-VT rather than operating on the current foreground
console. This means that the VT switches added in 1:0.2.3dbs-51 in
response to bug #226457 are unnecessary if you're running a more recent
kernel. Please apply the attached patch to 220_unimap_vts.patch, which
checks the kernel version and disables the VT switches if possible.

Changelog entry:

  * 220_unimap_vts.patch: Linux 2.6.1 fixed the GIO_UNIMAP, PIO_UNIMAP, and
    PIO_UNIMAPCLR ioctls to be per-VT rather than always using the current
    foreground console. If we're running on Linux 2.6.1 or newer, suppress
    the VT switch.

(Yes, I know I should probably switch to kbd, but Ubuntu is currently in
feature freeze so I'm sticking with console-tools for now ...)

Thanks,

-- 
Colin Watson                                       [EMAIL PROTECTED]
--- console-tools-0.2.3dbs.orig/debian/patches/220_unimap_vts.patch     
2006-06-29 10:42:54.000000000 +0100
+++ console-tools-0.2.3dbs/debian/patches/220_unimap_vts.patch  2006-09-08 
11:03:45.000000000 +0100
@@ -1,17 +1,45 @@
 diff -ruN console-tools-0.2.3-old/lib/sfm-misc.c 
console-tools-0.2.3/lib/sfm-misc.c
 --- console-tools-0.2.3-old/lib/sfm-misc.c     1999-04-08 22:29:39.000000000 
+0100
-+++ console-tools-0.2.3/lib/sfm-misc.c 2004-04-18 11:54:52.000000000 +0100
-@@ -13,15 +13,67 @@
++++ console-tools-0.2.3/lib/sfm-misc.c 2006-09-08 10:55:33.000000000 +0100
+@@ -13,15 +13,95 @@
  #include <ctype.h>
  #include <fcntl.h>
  #include <linux/kd.h>
 +#include <linux/vt.h>
  #include <sys/ioctl.h>
 +#include <sys/stat.h>
++#include <sys/utsname.h>
  
  #include <lct/local.h>
  #include <lct/console.h>
  
++/* Linux 2.6.1 introduced per-VT UNIMAP ioctls, so with that kernel or
++ * better we don't need to switch VTs.
++ */
++static int per_vt_unimap(void)
++{
++  static int per_vt = -1;
++  struct utsname uts;
++  int major_high, major_low, minor;
++
++  if (per_vt != -1) {
++    return per_vt;
++  }
++  if (uname(&uts) < 0) {
++    return per_vt = 0;
++  }
++  if (strcmp(uts.sysname, "Linux")) {
++    return per_vt = 0;
++  }
++  if (sscanf(uts.release, "%d.%d.%d", &major_high, &major_low, &minor) < 3) {
++    return per_vt = 0;
++  }
++  if (major_high < 2 || major_low < 6 || minor < 1)
++    return per_vt = 0;
++  else
++    return per_vt = 1;
++}
++
 +static int set_fd_foreground(int fd)
 +{
 +  struct vt_stat vstate;
@@ -69,35 +97,39 @@
  
    /* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP
     printf does not work. */
-@@ -30,6 +82,7 @@
+@@ -30,6 +110,8 @@
    advice.advised_hashstep = 0;
    advice.advised_hashlevel = 1;              /* FIXME: 0 or 1 ? */
    
-+  oldcon = set_fd_foreground(fd);
++  if (!per_vt_unimap())
++    oldcon = set_fd_foreground(fd);
  again:
    if (ioctl(fd, PIO_UNIMAPCLR, &advice)) 
      {
-@@ -41,6 +94,7 @@
+@@ -41,6 +123,8 @@
        } 
        else
  #endif
-+          restore_fd_foreground(fd, oldcon);
++        if (!per_vt_unimap())
++          restore_fd_foreground(fd, oldcon);
          return -1;
      }
    
-@@ -51,9 +105,10 @@
+@@ -51,9 +135,13 @@
          advice.advised_hashlevel++;
          goto again;
        }
-+      restore_fd_foreground(fd, oldcon);
++      if (!per_vt_unimap())
++      restore_fd_foreground(fd, oldcon);
        return -1;
      }
--  
-+  restore_fd_foreground(fd, oldcon);
+   
++  if (!per_vt_unimap())
++    restore_fd_foreground(fd, oldcon);
    return 0;
  }
  
-@@ -61,15 +116,18 @@
+@@ -61,15 +149,20 @@
  int get_kernel_unimap(int fd, struct unimapdesc *descr)
  {
    int ct;
@@ -106,35 +138,40 @@
    descr->entry_ct = 0;
    descr->entries = NULL;
    
-+  con = set_fd_foreground(fd);
++  if (!per_vt_unimap())
++    con = set_fd_foreground(fd);
    /* get entry_ct */
    if(ioctl(fd, GIO_UNIMAP, (unsigned long) descr)) /* failed */
      {
        if(errno != ENOMEM || descr->entry_ct == 0)
        {
-+        restore_fd_foreground(fd, con);
++        if (!per_vt_unimap())
++          restore_fd_foreground(fd, con);
          perror(_("GIO_UNIMAP (get count)"));
          return -1;
        }
-@@ -84,10 +142,13 @@
+@@ -84,10 +177,15 @@
        /* actually get unipairs */
        if(ioctl(fd, GIO_UNIMAP, (unsigned long) descr))
        {
-+        restore_fd_foreground(fd, con);
++        if (!per_vt_unimap())
++          restore_fd_foreground(fd, con);
          perror(_("GIO_UNIMAP (get map)"));
          return -1;
        }
  
-+      restore_fd_foreground(fd, con);
++      if (!per_vt_unimap())
++      restore_fd_foreground(fd, con);
 +
        /* someone could change the unimap between our
         * first and second ioctl, so we can have descrepancies
         */
-@@ -106,6 +167,7 @@
+@@ -106,6 +204,8 @@
      }
    else
      {
-+      restore_fd_foreground(fd, con);
++      if (!per_vt_unimap())
++      restore_fd_foreground(fd, con);
        /* no valid SFM currently loaded */
        errno = ENXIO;
        return -1;

Reply via email to