| /* |
| * 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)); |
| } |