| /* Copyright (C) 2000 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. */ |
| |
| #include <errno.h> |
| #include <termios.h> |
| #include "aix-termios.h" |
| |
| int |
| tcsetattr (fd, optional_actions, linuxtermios_p) |
| int fd; |
| int optional_actions; |
| const struct termios *linuxtermios_p; |
| { |
| struct aixtermios aixtermios; |
| int result; |
| |
| /* `optional_actions' does not have to be changed, AIX uses the |
| same values as Linux. */ |
| |
| aixtermios.c_cc[AIX_VINTR] = linuxtermios_p->c_cc[VINTR]; |
| aixtermios.c_cc[AIX_VQUIT] = linuxtermios_p->c_cc[VQUIT]; |
| aixtermios.c_cc[AIX_VERASE] = linuxtermios_p->c_cc[VERASE]; |
| aixtermios.c_cc[AIX_VKILL] = linuxtermios_p->c_cc[VKILL]; |
| aixtermios.c_cc[AIX_VEOF] = linuxtermios_p->c_cc[VEOF]; |
| // XXX VMIN has the same value as VEOF !? |
| aixtermios.c_cc[AIX_VEOL] = linuxtermios_p->c_cc[VEOL]; |
| // XXX VTIME has the same value as VEOL !? |
| aixtermios.c_cc[AIX_VEOL2] = linuxtermios_p->c_cc[VEOL2]; |
| aixtermios.c_cc[AIX_VSTART] = linuxtermios_p->c_cc[VSTART]; |
| aixtermios.c_cc[AIX_VSTOP] = linuxtermios_p->c_cc[VSTOP]; |
| aixtermios.c_cc[AIX_VSUSP] = linuxtermios_p->c_cc[VSUSP]; |
| aixtermios.c_cc[AIX_VDSUSP] = 0; // XXX No Linux equivalent !? |
| aixtermios.c_cc[AIX_VREPRINT] = linuxtermios_p->c_cc[VREPRINT]; |
| aixtermios.c_cc[AIX_VDISCARD] = linuxtermios_p->c_cc[VDISCARD]; |
| aixtermios.c_cc[AIX_VWERASE] = linuxtermios_p->c_cc[VWERASE]; |
| aixtermios.c_cc[AIX_VLNEXT] = linuxtermios_p->c_cc[VLNEXT]; |
| |
| /* AIX has not all the speeds (the high one) Linux supports. The |
| symbol names and values used for the speeds are fortunately the |
| same. */ |
| if ((linuxtermios_p->c_cflag & CBAUD) > B38400) |
| { |
| __set_errno (EINVAL); |
| return -1; |
| } |
| |
| aixtermios.c_c_flag = linuxtermios_p->c_cflag & CBAUD; |
| |
| /* Only the IUCLC, IXANY, and IMAXBEL values are different in the |
| c_iflag member. */ |
| aixtermios.c_iflag = linuxtermios_p->c_iflag & 0x7ff; |
| if (linuxtermios_p->c_iflag & IXANY) |
| aixtermios.c_iflag |= AIX_IXANY; |
| if (linuxtermios_p->c_iflag & IUCLC) |
| aixtermios.c_iflag |= AIX_IUCLC; |
| if (linuxtermios_p->c_iflag & IMAXBEL) |
| aixtermios.c_iflag |= AIX_IMAXBEL; |
| |
| /* Many of the c_oflag files differ. Bummer. */ |
| aixtermios.c_oflag = (linuxtermios_p->c_oflag |
| & (OPOST | OCRNL | ONOCR | ONLRET | OFILL |
| | OFDEL | TABDLY)); |
| if (linuxtermios_p->c_oflag & OLCUC) |
| aixtermios.c_oflag |= AIX_OLCUC; |
| if (linuxtermios_p->c_oflag & ONLCR) |
| aixtermios.c_oflag |= AIX_ONLCR; |
| if (linuxtermios_p->c_oflag & NLDLY) |
| { |
| if ((linuxtermios_p->c_oflag & NLDLY) >= NL2) |
| { |
| __set_errno (EINVAL); |
| return -1; |
| } |
| |
| if (linuxtermios_p->c_oflag & NLDLY) |
| aixtermios.c_oflag |= AIX_NL1; |
| } |
| if (linuxtermios_p->c_oflag & TABDLY) |
| { |
| #define offset 2 |
| #if TAB1 >> offset != AIX_TAB1 || TAB3 >> offset != AIX_TAB3 |
| # error "Check the offset" |
| #endif |
| aixtermios.c_oflag |= (linuxtermios_p->c_oflag >> offset) & AIX_TABDLY; |
| #undef offset |
| } |
| if (linuxtermios_p->c_oflag & FFDLY) |
| aixtermios.c_oflag |= AIX_FF1; |
| if (linuxtermios_p->c_oflag & BSDLY) |
| aixtermios.c_oflag |= AIX_BS1; |
| if (linuxtermios_p->c_oflag & VTDLY) |
| aixtermios.c_oflag |= AIX_VT1; |
| |
| /* A lot of the c_cflag member is also different. */ |
| if (linuxtermios_p->c_cflag & CSIZE) |
| { |
| #define offset 4 |
| #if CSIZE >> offset != AIX_CSIZE |
| # error "Check the offset" |
| #endif |
| aixtermios.c_cflag |= (linuxtermios_p->c_cflag >> offset) & AIX_CSIZE; |
| #undef offset |
| } |
| |
| if (linuxtermios_p->c_cflag & STOPB) |
| aixtermios.c_cflag |= AIX_STOPB; |
| if (linuxtermios_p->c_cflag & CREAD) |
| aixtermios.c_cflag |= AIX_CREAD; |
| if (linuxtermios_p->c_cflag & PARENB) |
| aixtermios.c_cflag |= AIX_PARENB; |
| if (linuxtermios_p->c_cflag & PARODD) |
| aixtermios.c_cflag |= AIX_PARODD; |
| if (linuxtermios_p->c_cflag & HUPCL) |
| aixtermios.c_cflag |= AIX_HUPCL; |
| if (linuxtermios_p->c_cflag & CLOCAL) |
| aixtermios.c_cflag |= AIX_CLOCAL; |
| |
| /* The c_lflag is information is also different. */ |
| aixtermios.c_lflag = 0; |
| if (linuxtermios_p->c_lflag & ISIG) |
| aixtermios.c_lflag |= AIX_ISIG; |
| if (linuxtermios_p->c_lflag & ICANON) |
| aixtermios.c_lflag |= AIX_ICANON; |
| if (linuxtermios_p->c_lflag & XCASE) |
| aixtermios.c_lflag |= AIX_XCASE; |
| if (linuxtermios_p->c_lflag & ECHO) |
| aixtermios.c_lflag |= AIX_ECHO; |
| if (linuxtermios_p->c_lflag & ECHOE) |
| aixtermios.c_lflag |= AIX_ECHOE; |
| if (linuxtermios_p->c_lflag & ECHOK) |
| aixtermios.c_lflag |= AIX_ECHOK; |
| if (linuxtermios_p->c_lflag & ECHONL) |
| aixtermios.c_lflag |= AIX_ECHONL; |
| if (linuxtermios_p->c_lflag & NOFLSH) |
| aixtermios.c_lflag |= AIX_NOFLSH; |
| if (linuxtermios_p->c_lflag & TOSTOP) |
| aixtermios.c_lflag |= AIX_TOSTOP; |
| if (linuxtermios_p->c_lflag & ECHOCTL) |
| aixtermios.c_lflag |= AIX_ECHOCTL; |
| if (linuxtermios_p->c_lflag & ECHOPRT) |
| aixtermios.c_lflag |= AIX_ECHOPRT; |
| if (linuxtermios_p->c_lflag & ECHOKE) |
| aixtermios.c_lflag |= AIX_ECHOKE; |
| if (linuxtermios_p->c_lflag & FLUSHO) |
| aixtermios.c_lflag |= AIX_FLUSHO; |
| if (linuxtermios_p->c_lflag & PENDIN) |
| aixtermios.c_lflag |= AIX_PENDIN; |
| if (linuxtermios_p->c_lflag & IEXTEN) |
| aixtermios.c_lflag |= AIX_IEXTEN; |
| |
| result = /* XXX syscall */; |
| |
| // Convert error here or in syscall. |
| |
| return result; |
| } |