Blame SOURCES/glibc-fedora-linux-tcsetattr.patch

ce426f
diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c
ce426f
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c	2012-06-05 07:42:49.000000000 -0600
ce426f
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c	2012-06-07 12:15:21.831318623 -0600
ce426f
@@ -48,6 +48,7 @@ tcsetattr (fd, optional_actions, termios
ce426f
 {
ce426f
   struct __kernel_termios k_termios;
ce426f
   unsigned long int cmd;
ce426f
+  int retval;
ce426f
 
ce426f
   switch (optional_actions)
ce426f
     {
ce426f
@@ -79,6 +80,35 @@ tcsetattr (fd, optional_actions, termios
ce426f
   memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
ce426f
 	  __KERNEL_NCCS * sizeof (cc_t));
ce426f
 
ce426f
-  return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
ce426f
+  retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
ce426f
+
ce426f
+  if (retval == 0 && cmd == TCSETS)
ce426f
+    {
ce426f
+      /* The Linux kernel has a bug which silently ignore the invalid
ce426f
+        c_cflag on pty. We have to check it here. */
ce426f
+      int save = errno;
ce426f
+      retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
ce426f
+      if (retval)
ce426f
+       {
ce426f
+         /* We cannot verify if the setting is ok. We don't return
ce426f
+            an error (?). */
ce426f
+         __set_errno (save);
ce426f
+         retval = 0;
ce426f
+       }
ce426f
+      else if ((termios_p->c_cflag & (PARENB | CREAD))
ce426f
+              != (k_termios.c_cflag & (PARENB | CREAD))
ce426f
+              || ((termios_p->c_cflag & CSIZE)
ce426f
+                  && ((termios_p->c_cflag & CSIZE)
ce426f
+                      != (k_termios.c_cflag & CSIZE))))
ce426f
+       {
ce426f
+         /* It looks like the Linux kernel silently changed the
ce426f
+            PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
ce426f
+            error. */
ce426f
+         __set_errno (EINVAL);
ce426f
+         retval = -1;
ce426f
+       }
ce426f
+    }
ce426f
+
ce426f
+  return retval;
ce426f
 }
ce426f
 libc_hidden_def (tcsetattr)