diff options
| -rw-r--r-- | libc/termios/kernel_termios.h | 157 | ||||
| -rw-r--r-- | libc/termios/tcgetattr.c | 72 | ||||
| -rw-r--r-- | libc/termios/tcsetattr.c | 116 | ||||
| -rw-r--r-- | libc/termios/termios.c | 23 | 
4 files changed, 240 insertions, 128 deletions
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 <sys/types.h> - -/* 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 <asm/termios.h>  -#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 <termios.h> -#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 <features.h> +#define __USE_GNU  #include <string.h> +#include <termios.h>  #include <unistd.h>  #include <sys/ioctl.h>  #include <sys/types.h> @@ -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 <errno.h>  #include <string.h> +#include <termios.h>  #include <sys/ioctl.h>  #include <sys/types.h> @@ -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 <sys/ioctl.h>  #include <sys/types.h>  #include <unistd.h> -#include "kernel_termios.h" +#include <termios.h>  #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;  | 
