330 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			330 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * shtty.c -- abstract interface to the terminal, focusing on capabilities.
 | |
|  */
 | |
| 
 | |
| /* Copyright (C) 1999 Free Software Foundation, Inc.
 | |
| 
 | |
|    This file is part of GNU Bash, the Bourne Again SHell.
 | |
| 
 | |
|    Bash is free software: you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation, either version 3 of the License, or
 | |
|    (at your option) any later version.
 | |
| 
 | |
|    Bash 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 General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #  include <config.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_UNISTD_H
 | |
| #  include <unistd.h>
 | |
| #endif
 | |
| 
 | |
| #include <shtty.h>
 | |
| 
 | |
| static TTYSTRUCT ttin, ttout;
 | |
| static int ttsaved = 0;
 | |
| 
 | |
| int
 | |
| ttgetattr(fd, ttp)
 | |
| int	fd;
 | |
| TTYSTRUCT *ttp;
 | |
| {
 | |
| #ifdef TERMIOS_TTY_DRIVER
 | |
|   return tcgetattr(fd, ttp);
 | |
| #else
 | |
| #  ifdef TERMIO_TTY_DRIVER
 | |
|   return ioctl(fd, TCGETA, ttp);
 | |
| #  else
 | |
|   return ioctl(fd, TIOCGETP, ttp);
 | |
| #  endif
 | |
| #endif
 | |
| }
 | |
| 
 | |
| int
 | |
| ttsetattr(fd, ttp)
 | |
| int	fd;
 | |
| TTYSTRUCT *ttp;
 | |
| {
 | |
| #ifdef TERMIOS_TTY_DRIVER
 | |
|   return tcsetattr(fd, TCSADRAIN, ttp);
 | |
| #else
 | |
| #  ifdef TERMIO_TTY_DRIVER
 | |
|   return ioctl(fd, TCSETAW, ttp);
 | |
| #  else
 | |
|   return ioctl(fd, TIOCSETN, ttp);
 | |
| #  endif
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| ttsave()
 | |
| {
 | |
|   if (ttsaved)
 | |
|    return;
 | |
|   ttgetattr (0, &ttin);
 | |
|   ttgetattr (1, &ttout);
 | |
|   ttsaved = 1;
 | |
| }
 | |
| 
 | |
| void
 | |
| ttrestore()
 | |
| {
 | |
|   if (ttsaved == 0)
 | |
|     return;
 | |
|   ttsetattr (0, &ttin);
 | |
|   ttsetattr (1, &ttout);
 | |
|   ttsaved = 0;
 | |
| }
 | |
| 
 | |
| /* Retrieve the internally-saved attributes associated with tty fd FD. */
 | |
| TTYSTRUCT *
 | |
| ttattr (fd)
 | |
|      int fd;
 | |
| {
 | |
|   if (ttsaved == 0)
 | |
|     return ((TTYSTRUCT *)0);
 | |
|   if (fd == 0)
 | |
|     return &ttin;
 | |
|   else if (fd == 1)
 | |
|     return &ttout;
 | |
|   else
 | |
|     return ((TTYSTRUCT *)0);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Change attributes in ttp so that when it is installed using
 | |
|  * ttsetattr, the terminal will be in one-char-at-a-time mode.
 | |
|  */
 | |
| int
 | |
| tt_setonechar(ttp)
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
| #if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
 | |
| 
 | |
|   /* XXX - might not want this -- it disables erase and kill processing. */
 | |
|   ttp->c_lflag &= ~ICANON;
 | |
| 
 | |
|   ttp->c_lflag |= ISIG;
 | |
| #  ifdef IEXTEN
 | |
|   ttp->c_lflag |= IEXTEN;
 | |
| #  endif
 | |
| 
 | |
|   ttp->c_iflag |= ICRNL;	/* make sure we get CR->NL on input */
 | |
|   ttp->c_iflag &= ~INLCR;	/* but no NL->CR */
 | |
| 
 | |
| #  ifdef OPOST
 | |
|   ttp->c_oflag |= OPOST;
 | |
| #  endif
 | |
| #  ifdef ONLCR
 | |
|   ttp->c_oflag |= ONLCR;
 | |
| #  endif
 | |
| #  ifdef OCRNL
 | |
|   ttp->c_oflag &= ~OCRNL;
 | |
| #  endif
 | |
| #  ifdef ONOCR
 | |
|   ttp->c_oflag &= ~ONOCR;
 | |
| #  endif
 | |
| #  ifdef ONLRET
 | |
|   ttp->c_oflag &= ~ONLRET;
 | |
| #  endif
 | |
| 
 | |
|   ttp->c_cc[VMIN] = 1;
 | |
|   ttp->c_cc[VTIME] = 0;
 | |
| 
 | |
| #else
 | |
| 
 | |
|   ttp->sg_flags |= CBREAK;
 | |
| 
 | |
| #endif
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /* Set the tty associated with FD and TTP into one-character-at-a-time mode */
 | |
| int
 | |
| ttfd_onechar (fd, ttp)
 | |
|      int fd;
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_setonechar(ttp) < 0)
 | |
|     return -1;
 | |
|   return (ttsetattr (fd, ttp));
 | |
| }
 | |
| 
 | |
| /* Set the terminal into one-character-at-a-time mode */
 | |
| int
 | |
| ttonechar ()
 | |
| {
 | |
|   TTYSTRUCT tt;
 | |
| 
 | |
|   if (ttsaved == 0)
 | |
|     return -1;
 | |
|   tt = ttin;
 | |
|   return (ttfd_onechar (0, &tt));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Change attributes in ttp so that when it is installed using
 | |
|  * ttsetattr, the terminal will be in no-echo mode.
 | |
|  */
 | |
| int
 | |
| tt_setnoecho(ttp)
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
| #if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
 | |
|   ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL);
 | |
| #else
 | |
|   ttp->sg_flags &= ~ECHO;
 | |
| #endif
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /* Set the tty associated with FD and TTP into no-echo mode */
 | |
| int
 | |
| ttfd_noecho (fd, ttp)
 | |
|      int fd;
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_setnoecho (ttp) < 0)
 | |
|     return -1;
 | |
|   return (ttsetattr (fd, ttp));
 | |
| }
 | |
| 
 | |
| /* Set the terminal into no-echo mode */
 | |
| int
 | |
| ttnoecho ()
 | |
| {
 | |
|   TTYSTRUCT tt;
 | |
| 
 | |
|   if (ttsaved == 0)
 | |
|     return -1;
 | |
|   tt = ttin;
 | |
|   return (ttfd_noecho (0, &tt));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Change attributes in ttp so that when it is installed using
 | |
|  * ttsetattr, the terminal will be in eight-bit mode (pass8).
 | |
|  */
 | |
| int
 | |
| tt_seteightbit (ttp)
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
| #if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
 | |
|   ttp->c_iflag &= ~ISTRIP;
 | |
|   ttp->c_cflag |= CS8;
 | |
|   ttp->c_cflag &= ~PARENB;
 | |
| #else
 | |
|   ttp->sg_flags |= ANYP;
 | |
| #endif
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /* Set the tty associated with FD and TTP into eight-bit mode */
 | |
| int
 | |
| ttfd_eightbit (fd, ttp)
 | |
|      int fd;
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_seteightbit (ttp) < 0)
 | |
|     return -1;
 | |
|   return (ttsetattr (fd, ttp));
 | |
| }
 | |
| 
 | |
| /* Set the terminal into eight-bit mode */
 | |
| int
 | |
| tteightbit ()
 | |
| {
 | |
|   TTYSTRUCT tt;
 | |
| 
 | |
|   if (ttsaved == 0)
 | |
|     return -1;
 | |
|   tt = ttin;
 | |
|   return (ttfd_eightbit (0, &tt));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Change attributes in ttp so that when it is installed using
 | |
|  * ttsetattr, the terminal will be in non-canonical input mode.
 | |
|  */
 | |
| int
 | |
| tt_setnocanon (ttp)
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
| #if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
 | |
|   ttp->c_lflag &= ~ICANON;
 | |
| #endif
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /* Set the tty associated with FD and TTP into non-canonical mode */
 | |
| int
 | |
| ttfd_nocanon (fd, ttp)
 | |
|      int fd;
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_setnocanon (ttp) < 0)
 | |
|     return -1;
 | |
|   return (ttsetattr (fd, ttp));
 | |
| }
 | |
| 
 | |
| /* Set the terminal into non-canonical mode */
 | |
| int
 | |
| ttnocanon ()
 | |
| {
 | |
|   TTYSTRUCT tt;
 | |
| 
 | |
|   if (ttsaved == 0)
 | |
|     return -1;
 | |
|   tt = ttin;
 | |
|   return (ttfd_nocanon (0, &tt));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Change attributes in ttp so that when it is installed using
 | |
|  * ttsetattr, the terminal will be in cbreak, no-echo mode.
 | |
|  */
 | |
| int
 | |
| tt_setcbreak(ttp)
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_setonechar (ttp) < 0)
 | |
|     return -1;
 | |
|   return (tt_setnoecho (ttp));
 | |
| }
 | |
| 
 | |
| /* Set the tty associated with FD and TTP into cbreak (no-echo,
 | |
|    one-character-at-a-time) mode */
 | |
| int
 | |
| ttfd_cbreak (fd, ttp)
 | |
|      int fd;
 | |
|      TTYSTRUCT *ttp;
 | |
| {
 | |
|   if (tt_setcbreak (ttp) < 0)
 | |
|     return -1;
 | |
|   return (ttsetattr (fd, ttp));
 | |
| }
 | |
| 
 | |
| /* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
 | |
| int
 | |
| ttcbreak ()
 | |
| {
 | |
|   TTYSTRUCT tt;
 | |
| 
 | |
|   if (ttsaved == 0)
 | |
|     return -1;
 | |
|   tt = ttin;
 | |
|   return (ttfd_cbreak (0, &tt));
 | |
| }
 | 
