As reported by John Hughes on
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=462626, Splashy is a small
boot splash program that starts from initramfs during early boot on Linux.
While Splashy is running, the contents of root (/) gets umounted and cleaned
up loosing access to the devices when the system started.

Using the following patch, when libdirectfb detects zero length reads, it
attempts to reopen the console (possibly from a newly mounted root tree).

This was the same solution that was suggested to us by Dennis a few months
ago. John arrived to the same conclusion independently (and submitted a
patch!)

-- 
----)(-----
Luis Mondesi
Maestro Debiano

----- START ENCRYPTED BLOCK (Triple-ROT13) ------
Gur Hohagh [Yvahk] qvfgevohgvba oevatf gur fcvevg bs Hohagh gb gur fbsgjner
jbeyq.
----- END ENCRYPTED BLOCK (Triple-ROT13) ------
--- directfb-1.0.1-orig/systems/fbdev/vt.h	2007-08-07 21:43:00.000000000 +0200
+++ directfb-1.0.1/systems/fbdev/vt.h	2008-04-02 23:14:48.000000000 +0200
@@ -34,7 +34,7 @@
 
 #include <directfb.h>
 
-typedef struct {
+typedef struct VirtualTerminal {
      int fd0;                      /* file descriptor of /dev/tty0 */
      int fd;                       /* file descriptor of /dev/ttyN
                                       where N is the number of the allocated VT,
@@ -56,6 +56,8 @@
      pthread_cond_t   wait;
 
      int              vt_sig;
+
+     DFBResult	     (*method_open) (struct VirtualTerminal *);
 } VirtualTerminal;
 
 /*
--- directfb-1.0.1-orig/systems/fbdev/vt.c	2007-08-07 21:43:00.000000000 +0200
+++ directfb-1.0.1/systems/fbdev/vt.c	2008-04-02 23:07:44.000000000 +0200
@@ -96,6 +96,8 @@
 static void      vt_set_fb( int vt, int fb );
 static void     *vt_thread( DirectThread *thread, void *arg );
 
+static DFBResult vt_open (VirtualTerminal *vt);
+
 DFBResult
 dfb_vt_initialize()
 {
@@ -219,6 +221,8 @@
           return ret;
      }
 
+     dfb_vt->method_open = &vt_open;
+
      dfb_fbdev->vt = dfb_vt;
 
      return DFB_OK;
@@ -439,27 +443,23 @@
 }
 
 static DFBResult
-vt_init_switching()
-{
-     const char cursoroff_str[] = "\033[?1;0;0c";
-     const char blankoff_str[] = "\033[9;0]";
+vt_open (VirtualTerminal *vt) {
+
      char buf[32];
 
      D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ );
 
-     /* FIXME: Opening the device should be moved out of this function. */
-
-     snprintf(buf, 32, "/dev/tty%d", dfb_vt->num);
-     dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
-     if (dfb_vt->fd < 0) {
+     snprintf(buf, 32, "/dev/tty%d", vt->num);
+     vt->fd = open( buf, O_RDWR | O_NOCTTY );
+     if (vt->fd < 0) {
           if (errno == ENOENT) {
-               snprintf(buf, 32, "/dev/vc/%d", dfb_vt->num);
-               dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
-               if (dfb_vt->fd < 0) {
+               snprintf(buf, 32, "/dev/vc/%d", vt->num);
+               vt->fd = open( buf, O_RDWR | O_NOCTTY );
+               if (vt->fd < 0) {
                     if (errno == ENOENT) {
                          D_PERROR( "DirectFB/core/vt: Couldn't open "
                                     "neither `/dev/tty%d' nor `/dev/vc/%d'!\n",
-                                    dfb_vt->num, dfb_vt->num );
+                                    vt->num, vt->num );
                     }
                     else {
                          D_PERROR( "DirectFB/core/vt: "
@@ -477,7 +477,24 @@
 
      /* attach to the new TTY before doing anything like KDSETMODE with it,
         otherwise we'd get access denied error: */
-     ioctl( dfb_vt->fd, TIOCSCTTY, 0 );
+     if (ioctl( vt->fd, TIOCSCTTY, 0 ) == -1) {
+	  return errno2result (errno);
+     }
+
+     return DFB_OK;
+}
+
+    
+static DFBResult
+vt_init_switching()
+{
+     const char cursoroff_str[] = "\033[?1;0;0c";
+     const char blankoff_str[] = "\033[9;0]";
+     DFBResult res;
+
+     D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ );
+
+     if ((res = vt_open (dfb_vt)) != DFB_OK) return res;
 
      write( dfb_vt->fd, cursoroff_str, sizeof(cursoroff_str) );
      if (dfb_config->kd_graphics) {
--- directfb-1.0.1-orig/inputdrivers/keyboard/keyboard.c	2007-08-07 21:43:00.000000000 +0200
+++ directfb-1.0.1/inputdrivers/keyboard/keyboard.c	2008-04-03 00:32:49.000000000 +0200
@@ -287,6 +287,18 @@
      ioctl( data->vt->fd, KDSKBLED, locks );
 }
 
+static void
+keyboard_set_input (KeyboardData *data)
+{
+     struct termios  ts;
+     ts = data->old_ts;
+     ts.c_cc[VTIME] = 0;
+     ts.c_cc[VMIN] = 1;
+     ts.c_lflag &= ~(ICANON|ECHO|ISIG);
+     ts.c_iflag = 0;
+     tcsetattr( data->vt->fd, TCSAFLUSH, &ts );
+}
+
 static void*
 keyboardEventThread( DirectThread *thread, void *driver_data )
 {
@@ -300,6 +312,13 @@
 
           direct_thread_testcancel( thread );
 
+	  if (readlen == 0) {
+	       /* Maybe our controlling terminal has been stolen by init */
+	       close (data->vt->fd);
+	       if (data->vt->method_open (data->vt) != DFB_OK) break;
+	       keyboard_set_input (data);
+	  }
+
           for (i = 0; i < readlen; i++) {
                DFBInputEvent evt;
 
@@ -351,7 +370,6 @@
                     InputDeviceInfo  *info,
                     void            **driver_data )
 {
-     struct termios  ts;
      KeyboardData   *data;
      FBDev          *dfb_fbdev = dfb_system_data();
 
@@ -369,12 +387,7 @@
 
      tcgetattr( data->vt->fd, &data->old_ts );
 
-     ts = data->old_ts;
-     ts.c_cc[VTIME] = 0;
-     ts.c_cc[VMIN] = 1;
-     ts.c_lflag &= ~(ICANON|ECHO|ISIG);
-     ts.c_iflag = 0;
-     tcsetattr( data->vt->fd, TCSAFLUSH, &ts );
+     keyboard_set_input (data);
 
      tcsetpgrp( data->vt->fd, getpgrp() );
 
_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to