* sysdeps/unix/sysv/linux/mips/sys/ucontext.h: Use array for
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / tcsetattr.c
1 /* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <errno.h>
20 #include <stddef.h>
21 #include <termios.h>
22 #include <sys/ioctl.h>
23
24 #include <sysv_termio.h>
25
26
27 const speed_t __unix_speeds[] =
28   {
29     0,
30     50,
31     75,
32     110,
33     134,
34     150,
35     200,
36     300,
37     600,
38     1200,
39     1800,
40     2400,
41     4800,
42     9600,
43     19200,
44     38400,
45   };
46
47
48 /* Set the state of FD to *TERMIOS_P.  */
49 int
50 tcsetattr (fd, optional_actions, termios_p)
51      int fd;
52      int optional_actions;
53      const struct termios *termios_p;
54 {
55   struct __sysv_termio buf;
56   int ioctl_function;
57   size_t i;
58
59   if (termios_p == NULL)
60     {
61       __set_errno (EINVAL);
62       return -1;
63     }
64   switch (optional_actions)
65     {
66     case TCSANOW:
67       ioctl_function = _TCSETA;
68       break;
69     case TCSADRAIN:
70       ioctl_function = _TCSETAW;
71       break;
72     case TCSAFLUSH:
73       ioctl_function = _TCSETAF;
74       break;
75     default:
76       __set_errno (EINVAL);
77       return -1;
78     }
79
80   if (termios_p->__ispeed != termios_p->__ospeed)
81     {
82       __set_errno (EINVAL);
83       return -1;
84     }
85   buf.c_cflag = -1;
86   for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i)
87     {
88       if (__unix_speeds[i] == termios_p->__ispeed)
89         buf.c_cflag = i;
90     }
91   if (buf.c_cflag == -1)
92     {
93       __set_errno (EINVAL);
94       return -1;
95     }
96
97   buf.c_iflag = 0;
98   if (termios_p->c_iflag & IGNBRK)
99     buf.c_iflag |= _SYSV_IGNBRK;
100   if (termios_p->c_iflag & BRKINT)
101     buf.c_iflag |= _SYSV_BRKINT;
102   if (termios_p->c_iflag & IGNPAR)
103     buf.c_iflag |= _SYSV_IGNPAR;
104   if (termios_p->c_iflag & PARMRK)
105     buf.c_iflag |= _SYSV_PARMRK;
106   if (termios_p->c_iflag & INPCK)
107     buf.c_iflag |= _SYSV_INPCK;
108   if (termios_p->c_iflag & ISTRIP)
109     buf.c_iflag |= _SYSV_ISTRIP;
110   if (termios_p->c_iflag & INLCR)
111     buf.c_iflag |= _SYSV_INLCR;
112   if (termios_p->c_iflag & IGNCR)
113     buf.c_iflag |= _SYSV_IGNCR;
114   if (termios_p->c_iflag & ICRNL)
115     buf.c_iflag |= _SYSV_ICRNL;
116   if (termios_p->c_iflag & IXON)
117     buf.c_iflag |= _SYSV_IXON;
118   if (termios_p->c_iflag & IXOFF)
119     buf.c_iflag |= _SYSV_IXOFF;
120   if (termios_p->c_iflag & IXANY)
121     buf.c_iflag |= _SYSV_IXANY;
122   if (termios_p->c_iflag & IMAXBEL)
123     buf.c_iflag |= _SYSV_IMAXBEL;
124
125   buf.c_oflag = 0;
126   if (termios_p->c_oflag & OPOST)
127     buf.c_oflag |= _SYSV_OPOST;
128   if (termios_p->c_oflag & ONLCR)
129     buf.c_oflag |= _SYSV_ONLCR;
130
131   /* So far, buf.c_cflag contains the speed in CBAUD.  */
132   if (termios_p->c_cflag & CSTOPB)
133     buf.c_cflag |= _SYSV_CSTOPB;
134   if (termios_p->c_cflag & CREAD)
135     buf.c_cflag |= _SYSV_CREAD;
136   if (termios_p->c_cflag & PARENB)
137     buf.c_cflag |= _SYSV_PARENB;
138   if (termios_p->c_cflag & PARODD)
139     buf.c_cflag |= _SYSV_PARODD;
140   if (termios_p->c_cflag & HUPCL)
141     buf.c_cflag |= _SYSV_HUPCL;
142   if (termios_p->c_cflag & CLOCAL)
143     buf.c_cflag |= _SYSV_CLOCAL;
144   switch (termios_p->c_cflag & CSIZE)
145     {
146     case CS5:
147       buf.c_cflag |= _SYSV_CS5;
148       break;
149     case CS6:
150       buf.c_cflag |= _SYSV_CS6;
151       break;
152     case CS7:
153       buf.c_cflag |= _SYSV_CS7;
154       break;
155     case CS8:
156       buf.c_cflag |= _SYSV_CS8;
157       break;
158     }
159
160   buf.c_lflag = 0;
161   if (termios_p->c_lflag & ISIG)
162     buf.c_lflag |= _SYSV_ISIG;
163   if (termios_p->c_lflag & ICANON)
164     buf.c_lflag |= _SYSV_ICANON;
165   if (termios_p->c_lflag & ECHO)
166     buf.c_lflag |= _SYSV_ECHO;
167   if (termios_p->c_lflag & ECHOE)
168     buf.c_lflag |= _SYSV_ECHOE;
169   if (termios_p->c_lflag & ECHOK)
170     buf.c_lflag |= _SYSV_ECHOK;
171   if (termios_p->c_lflag & ECHONL)
172     buf.c_lflag |= _SYSV_ECHONL;
173   if (termios_p->c_lflag & NOFLSH)
174     buf.c_lflag |= _SYSV_NOFLSH;
175   if (termios_p->c_lflag & TOSTOP)
176     buf.c_lflag |= _SYSV_TOSTOP;
177   if (termios_p->c_lflag & ECHOCTL)
178     buf.c_lflag |= _SYSV_ECHOCTL;
179   if (termios_p->c_lflag & ECHOPRT)
180     buf.c_lflag |= _SYSV_ECHOPRT;
181   if (termios_p->c_lflag & ECHOKE)
182     buf.c_lflag |= _SYSV_ECHOKE;
183   if (termios_p->c_lflag & FLUSHO)
184     buf.c_lflag |= _SYSV_FLUSHO;
185   if (termios_p->c_lflag & PENDIN)
186     buf.c_lflag |= _SYSV_PENDIN;
187   if (termios_p->c_lflag & IEXTEN)
188     buf.c_lflag |= _SYSV_IEXTEN;
189
190   buf.c_cc[_SYSV_VINTR] = termios_p->c_cc[VINTR];
191   buf.c_cc[_SYSV_VQUIT] = termios_p->c_cc[VQUIT];
192   buf.c_cc[_SYSV_VERASE] = termios_p->c_cc[VERASE];
193   buf.c_cc[_SYSV_VKILL] = termios_p->c_cc[VKILL];
194   if (buf.c_lflag & _SYSV_ICANON)
195     {
196       buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF];
197       buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL];
198     }
199   else
200     {
201       buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN];
202       buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME];
203     }
204   buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2];
205
206   if (__ioctl (fd, ioctl_function, &buf) < 0)
207     return -1;
208   return 0;
209 }