diff options
Diffstat (limited to 'sysdeps/unix/bsd/tcsetattr.c')
-rw-r--r-- | sysdeps/unix/bsd/tcsetattr.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/sysdeps/unix/bsd/tcsetattr.c b/sysdeps/unix/bsd/tcsetattr.c new file mode 100644 index 0000000000..e731d830f6 --- /dev/null +++ b/sysdeps/unix/bsd/tcsetattr.c @@ -0,0 +1,186 @@ +/* Copyright (C) 1991, 1993 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 Library General Public License as +published by the Free Software Foundation; either version 2 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. + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +#include "bsdtty.h" + + +CONST speed_t __bsd_speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + }; + + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + struct sgttyb buf; + struct tchars tchars; + struct ltchars ltchars; + int local; +#ifdef TIOCGETX + int extra; +#endif + size_t i; + + if (__ioctl(fd, TIOCGETP, &buf) < 0 || + __ioctl(fd, TIOCGETC, &tchars) < 0 || + __ioctl(fd, TIOCGLTC, <chars) < 0 || +#ifdef TIOCGETX + __ioctl(fd, TIOCGETX, &extra) < 0 || +#endif + __ioctl(fd, TIOCLGET, &local) < 0) + return -1; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + switch (optional_actions) + { + case TCSANOW: + break; + case TCSADRAIN: + if (tcdrain(fd) < 0) + return -1; + break; + case TCSAFLUSH: + if (tcflush(fd, TCIFLUSH) < 0) + return -1; + break; + default: + errno = EINVAL; + return -1; + } + + buf.sg_ispeed = buf.sg_ospeed = -1; + for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i) + { + if (__bsd_speeds[i] == termios_p->__ispeed) + buf.sg_ispeed = i; + if (__bsd_speeds[i] == termios_p->__ospeed) + buf.sg_ospeed = i; + } + if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1) + { + errno = EINVAL; + return -1; + } + + buf.sg_flags &= ~(CBREAK|RAW); + if (!(termios_p->c_lflag & ICANON)) + buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW; +#ifdef LPASS8 + if (termios_p->c_oflag & CS8) + local |= LPASS8; + else + local &= ~LPASS8; +#endif + if (termios_p->c_lflag & _NOFLSH) + local |= LNOFLSH; + else + local &= ~LNOFLSH; + if (termios_p->c_oflag & OPOST) + local &= ~LLITOUT; + else + local |= LLITOUT; +#ifdef TIOCGETX + if (termios_p->c_lflag & ISIG) + extra &= ~NOISIG; + else + extra |= NOISIG; + if (termios_p->c_cflag & CSTOPB) + extra |= STOPB; + else + extra &= ~STOPB; +#endif + if (termios_p->c_iflag & ICRNL) + buf.sg_flags |= CRMOD; + else + buf.sg_flags &= ~CRMOD; + if (termios_p->c_iflag & IXOFF) + buf.sg_flags |= TANDEM; + else + buf.sg_flags &= ~TANDEM; + + buf.sg_flags &= ~(ODDP|EVENP); + if (!(termios_p->c_cflag & PARENB)) + buf.sg_flags |= ODDP | EVENP; + else if (termios_p->c_cflag & PARODD) + buf.sg_flags |= ODDP; + else + buf.sg_flags |= EVENP; + + if (termios_p->c_lflag & _ECHO) + buf.sg_flags |= ECHO; + else + buf.sg_flags &= ~ECHO; + if (termios_p->c_lflag & ECHOE) + local |= LCRTERA; + else + local &= ~LCRTERA; + if (termios_p->c_lflag & ECHOK) + local |= LCRTKIL; + else + local &= ~LCRTKIL; + if (termios_p->c_lflag & _TOSTOP) + local |= LTOSTOP; + else + local &= ~LTOSTOP; + + buf.sg_erase = termios_p->c_cc[VERASE]; + buf.sg_kill = termios_p->c_cc[VKILL]; + tchars.t_eofc = termios_p->c_cc[VEOF]; + tchars.t_intrc = termios_p->c_cc[VINTR]; + tchars.t_quitc = termios_p->c_cc[VQUIT]; + ltchars.t_suspc = termios_p->c_cc[VSUSP]; + tchars.t_startc = termios_p->c_cc[VSTART]; + tchars.t_stopc = termios_p->c_cc[VSTOP]; + + if (__ioctl(fd, TIOCSETP, &buf) < 0 || + __ioctl(fd, TIOCSETC, &tchars) < 0 || + __ioctl(fd, TIOCSLTC, <chars) < 0 || +#ifdef TIOCGETX + __ioctl(fd, TIOCSETX, &extra) < 0 || +#endif + __ioctl(fd, TIOCLSET, &local) < 0) + return -1; + return 0; +} |