]> git.ipfire.org Git - ipfire-3.x.git/blob - glibc/patches/glibc-fedora-linux-tcsetattr.patch
066ac484b921c8730ba7d3af5b59dd7a2680b047
[ipfire-3.x.git] / glibc / patches / glibc-fedora-linux-tcsetattr.patch
1 diff -Nrup a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
2 --- a/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-05 07:42:49.000000000 -0600
3 +++ b/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-07 12:15:21.831318623 -0600
4 @@ -48,6 +48,7 @@ tcsetattr (fd, optional_actions, termios
5 {
6 struct __kernel_termios k_termios;
7 unsigned long int cmd;
8 + int retval;
9
10 switch (optional_actions)
11 {
12 @@ -79,6 +80,35 @@ tcsetattr (fd, optional_actions, termios
13 memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
14 __KERNEL_NCCS * sizeof (cc_t));
15
16 - return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
17 + retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
18 +
19 + if (retval == 0 && cmd == TCSETS)
20 + {
21 + /* The Linux kernel has a bug which silently ignore the invalid
22 + c_cflag on pty. We have to check it here. */
23 + int save = errno;
24 + retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
25 + if (retval)
26 + {
27 + /* We cannot verify if the setting is ok. We don't return
28 + an error (?). */
29 + __set_errno (save);
30 + retval = 0;
31 + }
32 + else if ((termios_p->c_cflag & (PARENB | CREAD))
33 + != (k_termios.c_cflag & (PARENB | CREAD))
34 + || ((termios_p->c_cflag & CSIZE)
35 + && ((termios_p->c_cflag & CSIZE)
36 + != (k_termios.c_cflag & CSIZE))))
37 + {
38 + /* It looks like the Linux kernel silently changed the
39 + PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
40 + error. */
41 + __set_errno (EINVAL);
42 + retval = -1;
43 + }
44 + }
45 +
46 + return retval;
47 }
48 libc_hidden_def (tcsetattr)