File glibc-2.3.2-revert_tcsetattr.diff of Package glibc

Index: sysdeps/unix/sysv/linux/tcsetattr.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/tcsetattr.c,v
retrieving revision 1.14
retrieving revision 1.13
diff -u -r1.14 -r1.13
--- sysdeps/unix/sysv/linux/tcsetattr.c	21 Feb 2003 00:09:04 -0000	1.14
+++ sysdeps/unix/sysv/linux/tcsetattr.c	17 Feb 2003 19:48:44 -0000	1.13
@@ -56,6 +56,7 @@
 {
   struct __kernel_termios k_termios;
   unsigned long int cmd;
+  int retval;
 
   switch (optional_actions)
     {
@@ -87,6 +88,35 @@
   memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
 	  __KERNEL_NCCS * sizeof (cc_t));
 
-  return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+  retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+
+  if (retval == 0 && cmd == TCSETS)
+    {
+      /* The Linux kernel has a bug which silently ignore the invalid
+	 c_cflag on pty. We have to check it here. */
+      int save = errno;
+      retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
+      if (retval)
+	{
+	  /* We cannot verify if the setting is ok. We don't return
+	     an error (?). */
+	  __set_errno (save);
+	  retval = 0;
+	}
+      else if ((termios_p->c_cflag & (PARENB | CREAD))
+	       != (k_termios.c_cflag & (PARENB | CREAD))
+	       || ((termios_p->c_cflag & CSIZE)
+		   && ((termios_p->c_cflag & CSIZE)
+		       != (k_termios.c_cflag & CSIZE))))
+	{
+	  /* It looks like the Linux kernel silently changed the
+	     PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
+	     error. */
+	  __set_errno (EINVAL);
+	  retval = -1;
+	}
+    }
+
+  return retval;
 }
 libc_hidden_def (tcsetattr)
openSUSE Build Service is sponsored by