From 2f2e72cbed35ff28d89ef16dbbea4497de834617 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 9 Jan 2002 19:40:21 +0000 Subject: Fixup broken termios stuff. No, really this time. -Erik --- libc/termios/kernel_termios.h | 157 +++++++++++++++++++++++++++++++++++------- libc/termios/tcgetattr.c | 72 ++++++++++--------- libc/termios/tcsetattr.c | 116 +++++++++++++++---------------- libc/termios/termios.c | 23 +++---- 4 files changed, 240 insertions(+), 128 deletions(-) (limited to 'libc/termios') diff --git a/libc/termios/kernel_termios.h b/libc/termios/kernel_termios.h index af6fb2aca..87d5c07e4 100644 --- a/libc/termios/kernel_termios.h +++ b/libc/termios/kernel_termios.h @@ -1,30 +1,139 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + #ifndef _KERNEL_TERMIOS_H #define _KERNEL_TERMIOS_H 1 -#include - -/* Pull in whatever this particular arch's kernel thinks the kernel version of - * struct termios should look like. It turns out that each arch has a different - * opinion on the subject, and different kernel revs use different names... */ -#define termio __kernel_termios -#define winsize __kernel_winsize -#define cc_t __kernel_cc_t -#define speed_t __kernel_speed_t -#define tcflag_t __kernel_tcflag_t -#undef NCCS -#include -#define __KERNEL_NCCS NCCS -#undef NCCS -#undef termio -#undef winsize -#undef cc_t -#undef speed_t -#undef tcflag_t - -/* Now pull in libc's version of termios */ -#define termios libc_termios +/* We need the definition of tcflag_t, cc_t, and speed_t. */ #include -#undef termios -#endif /* _KERNEL_TERMIOS_H */ +/* The following corresponds to the values from the Linux 2.1.20 kernel. */ + + + + +#if defined( __sparc__ ) + + +#define __KERNEL_NCCS 17 +struct __kernel_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[__KERNEL_NCCS]; /* control characters */ +}; + + + +#elif defined(__powerpc__) + + + +#define __KERNEL_NCCS 19 +struct __kernel_termios + { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[__KERNEL_NCCS]; /* control characters */ + cc_t c_line; /* line discipline */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ + }; + +#define _HAVE_C_ISPEED 1 +#define _HAVE_C_OSPEED 1 + +/* We have the kernel termios structure, so we can presume this code knows + what it's doing... */ +#undef TCGETS +#undef TCSETS +#undef TCSETSW +#undef TCSETSF +#define TCGETS _IOR ('t', 19, struct __kernel_termios) +#define TCSETS _IOW ('t', 20, struct __kernel_termios) +#define TCSETSW _IOW ('t', 21, struct __kernel_termios) +#define TCSETSF _IOW ('t', 22, struct __kernel_termios) + + + +#elif defined(__mips__) + + + +#define __KERNEL_NCCS 23 +struct __kernel_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[__KERNEL_NCCS]; /* control characters */ +}; + + + +#elif defined(__alpha__) + + + +#define __KERNEL_NCCS 19 +struct __kernel_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[__KERNEL_NCCS]; /* control characters */ + cc_t c_line; /* line discipline */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +#define _HAVE_C_ISPEED 1 +#define _HAVE_C_OSPEED 1 + + + +#else /* None of the above */ + + + +#define __KERNEL_NCCS 19 +struct __kernel_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[__KERNEL_NCCS]; /* control characters */ +}; + +#endif + + + + +#endif /* kernel_termios.h */ diff --git a/libc/termios/tcgetattr.c b/libc/termios/tcgetattr.c index b8728461a..8e011b95e 100644 --- a/libc/termios/tcgetattr.c +++ b/libc/termios/tcgetattr.c @@ -2,21 +2,24 @@ This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ +#include +#define __USE_GNU #include +#include #include #include #include @@ -27,40 +30,47 @@ #include "kernel_termios.h" /* Put the state of FD into *TERMIOS_P. */ -int tcgetattr ( int fd, struct libc_termios *termios_p) +int tcgetattr (int fd, struct termios *termios_p) { - struct __kernel_termios k_termios; - int retval; + struct __kernel_termios k_termios; + int retval; - retval = ioctl (fd, TCGETS, &k_termios); + retval = ioctl (fd, TCGETS, &k_termios); - termios_p->c_iflag = k_termios.c_iflag; - termios_p->c_oflag = k_termios.c_oflag; - termios_p->c_cflag = k_termios.c_cflag; - termios_p->c_lflag = k_termios.c_lflag; - termios_p->c_line = k_termios.c_line; + termios_p->c_iflag = k_termios.c_iflag; + termios_p->c_oflag = k_termios.c_oflag; + termios_p->c_cflag = k_termios.c_cflag; + termios_p->c_lflag = k_termios.c_lflag; + termios_p->c_line = k_termios.c_line; #ifdef _HAVE_C_ISPEED - termios_p->c_ispeed = k_termios.c_ispeed; + termios_p->c_ispeed = k_termios.c_ispeed; #endif #ifdef _HAVE_C_OSPEED - termios_p->c_ospeed = k_termios.c_ospeed; + termios_p->c_ospeed = k_termios.c_ospeed; #endif - if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0 - || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1) - memset ( (memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)) + (__KERNEL_NCCS * sizeof (cc_t))) , - _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); - else + + + if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0 + || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1) { - size_t cnt; + memset (mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)), + _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); +#if 0 + memset ( (memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)) + (__KERNEL_NCCS * sizeof (cc_t))) , + _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); +#endif + } else { + size_t cnt; - memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)); + memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)); - for (cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt) - termios_p->c_cc[cnt] = _POSIX_VDISABLE; + for (cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt) + termios_p->c_cc[cnt] = _POSIX_VDISABLE; } - return retval; + return retval; } diff --git a/libc/termios/tcsetattr.c b/libc/termios/tcsetattr.c index 9f8c172bd..83bf61d99 100644 --- a/libc/termios/tcsetattr.c +++ b/libc/termios/tcsetattr.c @@ -2,22 +2,23 @@ This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include #include +#include #include #include @@ -46,73 +47,70 @@ /* Set the state of FD to *TERMIOS_P. */ -int tcsetattr (fd, optional_actions, termios_p) - int fd; - int optional_actions; - const struct libc_termios *termios_p; +int tcsetattr (int fd, int optional_actions, const struct termios *termios_p) { - struct __kernel_termios k_termios; - unsigned long int cmd; - int retval; + struct __kernel_termios k_termios; + unsigned long int cmd; + int retval; - switch (optional_actions) + switch (optional_actions) { - case TCSANOW: - cmd = TCSETS; - break; - case TCSADRAIN: - cmd = TCSETSW; - break; - case TCSAFLUSH: - cmd = TCSETSF; - break; - default: - __set_errno(EINVAL); - return -1; + case TCSANOW: + cmd = TCSETS; + break; + case TCSADRAIN: + cmd = TCSETSW; + break; + case TCSAFLUSH: + cmd = TCSETSF; + break; + default: + __set_errno (EINVAL); + return -1; } - k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0; - k_termios.c_oflag = termios_p->c_oflag; - k_termios.c_cflag = termios_p->c_cflag; - k_termios.c_lflag = termios_p->c_lflag; - k_termios.c_line = termios_p->c_line; + k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0; + k_termios.c_oflag = termios_p->c_oflag; + k_termios.c_cflag = termios_p->c_cflag; + k_termios.c_lflag = termios_p->c_lflag; + k_termios.c_line = termios_p->c_line; #ifdef _HAVE_C_ISPEED - k_termios.c_ispeed = termios_p->c_ispeed; + k_termios.c_ispeed = termios_p->c_ispeed; #endif #ifdef _HAVE_C_OSPEED - k_termios.c_ospeed = termios_p->c_ospeed; + k_termios.c_ospeed = termios_p->c_ospeed; #endif - memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)); + memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)); - retval = ioctl (fd, cmd, &k_termios); + retval = ioctl (fd, cmd, &k_termios); - if (retval == 0 && cmd == TCSETS) + 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 = ioctl (fd, TCGETS, &k_termios); - if (retval) + /* 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 = ioctl (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; + /* 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)))) + 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; + /* 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; + return retval; } diff --git a/libc/termios/termios.c b/libc/termios/termios.c index a5b3b2776..24448c0e4 100644 --- a/libc/termios/termios.c +++ b/libc/termios/termios.c @@ -28,20 +28,15 @@ #include #include #include -#include "kernel_termios.h" +#include #ifdef L_isatty /* Return 1 if FD is a terminal, 0 if not. */ int isatty(int fd) { - struct __kernel_termios k_term; - - /* - * When ioctl returns -1 we want to return 0 and - * when ioctl returns 0 we want to return 1. - */ - return (ioctl(fd, TCGETS, &k_term)==0)? 1 : 0; + struct termios term; + return (tcgetattr (fd, &term) == 0); } #endif @@ -124,7 +119,7 @@ pid_t tcgetpgrp ( int fd) #ifdef L_cfgetospeed /* Return the output baud rate stored in *TERMIOS_P. */ -speed_t cfgetospeed ( const struct libc_termios *termios_p) +speed_t cfgetospeed ( const struct termios *termios_p) { return termios_p->c_cflag & (CBAUD | CBAUDEX); } @@ -136,7 +131,7 @@ speed_t cfgetospeed ( const struct libc_termios *termios_p) * Although for Linux there is no difference between input and output * speed, the numerical 0 is a special case for the input baud rate. It * should set the input baud rate to the output baud rate. */ -speed_t cfgetispeed (const struct libc_termios *termios_p) +speed_t cfgetispeed (const struct termios *termios_p) { return ((termios_p->c_iflag & IBAUD0) ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX)); @@ -145,7 +140,7 @@ speed_t cfgetispeed (const struct libc_termios *termios_p) #ifdef L_cfsetospeed /* Set the output baud rate stored in *TERMIOS_P to SPEED. */ -int cfsetospeed (struct libc_termios *termios_p, speed_t speed) +int cfsetospeed (struct termios *termios_p, speed_t speed) { if ((speed & ~CBAUD) != 0 && (speed < B57600 || speed > B460800)) @@ -166,7 +161,7 @@ int cfsetospeed (struct libc_termios *termios_p, speed_t speed) * Although for Linux there is no difference between input and output * speed, the numerical 0 is a special case for the input baud rate. It * should set the input baud rate to the output baud rate. */ -int cfsetispeed ( struct libc_termios *termios_p, speed_t speed) +int cfsetispeed ( struct termios *termios_p, speed_t speed) { if ((speed & ~CBAUD) != 0 && (speed < B57600 || speed > B460800)) @@ -273,7 +268,7 @@ static const struct speed_struct speeds[] = /* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */ -int cfsetspeed (struct libc_termios *termios_p, speed_t speed) +int cfsetspeed (struct termios *termios_p, speed_t speed) { size_t cnt; @@ -305,7 +300,7 @@ int cfsetspeed (struct libc_termios *termios_p, speed_t speed) /* Set *T to indicate raw mode. */ void -cfmakeraw (struct libc_termios *t) +cfmakeraw (struct termios *t) { t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); t->c_oflag &= ~OPOST; -- cgit v1.2.3