Formerly mach/hurd/telldir.c.~2~
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / tcsetattr.c
1 /* Copyright (C) 1992 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
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <ansidecl.h>
20 #include <errno.h>
21 #include <stddef.h>
22 #include <termios.h>
23 #include <sys/ioctl.h>
24
25 #include <sysv_termio.h>
26
27
28 CONST speed_t __unix_speeds[] =
29   {
30     0,
31     50,
32     75,
33     110,
34     134,
35     150,
36     200,
37     300,
38     600,
39     1200,
40     1800,
41     2400,
42     4800,
43     9600,
44     19200,
45     38400,
46   };
47
48
49 /* Set the state of FD to *TERMIOS_P.  */
50 int
51 DEFUN(tcsetattr, (fd, optional_actions, termios_p),
52       int fd AND int optional_actions AND CONST struct termios *termios_p)
53 {
54   struct __sysv_termio buf;
55   int ioctl_function;
56   size_t i;
57
58   if (termios_p == NULL)
59     {
60       errno = EINVAL;
61       return -1;
62     }
63   switch (optional_actions)
64     {
65     case TCSANOW:
66       ioctl_function = _TCSETA;
67       break;
68     case TCSADRAIN:
69       ioctl_function = _TCSETAW;
70       break;
71     case TCSAFLUSH:
72       ioctl_function = _TCSETAF;
73       break;
74     default:
75       errno = EINVAL;
76       return -1;
77     }
78
79   if (termios_p->__ispeed != termios_p->__ospeed)
80     {
81       errno = EINVAL;
82       return -1;
83     }
84   buf.c_cflag = -1;
85   for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i)
86     {
87       if (__unix_speeds[i] == termios_p->__ispeed)
88         buf.c_cflag = i;
89     }
90   if (buf.c_cflag == -1)
91     {
92       errno = EINVAL;
93       return -1;
94     }
95
96   buf.c_iflag = 0;
97   if (termios_p->c_iflag & IGNBRK)
98     buf.c_iflag |= _SYSV_IGNBRK;
99   if (termios_p->c_iflag & BRKINT)
100     buf.c_iflag |= _SYSV_BRKINT;
101   if (termios_p->c_iflag & IGNPAR)
102     buf.c_iflag |= _SYSV_IGNPAR;
103   if (termios_p->c_iflag & PARMRK)
104     buf.c_iflag |= _SYSV_PARMRK;
105   if (termios_p->c_iflag & INPCK)
106     buf.c_iflag |= _SYSV_INPCK;
107   if (termios_p->c_iflag & ISTRIP)
108     buf.c_iflag |= _SYSV_ISTRIP;
109   if (termios_p->c_iflag & INLCR)
110     buf.c_iflag |= _SYSV_INLCR;
111   if (termios_p->c_iflag & IGNCR)
112     buf.c_iflag |= _SYSV_IGNCR;
113   if (termios_p->c_iflag & ICRNL)
114     buf.c_iflag |= _SYSV_ICRNL;
115   if (termios_p->c_iflag & IXON)
116     buf.c_iflag |= _SYSV_IXON;
117   if (termios_p->c_iflag & IXOFF)
118     buf.c_iflag |= _SYSV_IXOFF;
119   if (termios_p->c_iflag & IXANY)
120     buf.c_iflag |= _SYSV_IXANY;
121   if (termios_p->c_iflag & IMAXBEL)
122     buf.c_iflag |= _SYSV_IMAXBEL;
123
124   buf.c_oflag = 0;
125   if (termios_p->c_oflag & OPOST)
126     buf.c_oflag = _SYSV_OPOST;
127   if (termios_p->c_oflag & ONLCR)
128     buf.c_oflag = _SYSV_ONLCR;
129
130   /* So far, buf.c_cflag contains the speed in CBAUD.  */
131   if (termios_p->c_cflag & CSTOPB)
132     buf.c_cflag |= _SYSV_CSTOPB;
133   if (termios_p->c_cflag & CREAD)
134     buf.c_cflag |= _SYSV_CREAD;
135   if (termios_p->c_cflag & PARENB)
136     buf.c_cflag |= _SYSV_PARENB;
137   if (termios_p->c_cflag & PARODD)
138     buf.c_cflag |= _SYSV_PARODD;
139   if (termios_p->c_cflag & HUPCL)
140     buf.c_cflag |= _SYSV_HUPCL;
141   if (termios_p->c_cflag & CLOCAL)
142     buf.c_cflag |= _SYSV_CLOCAL;
143   switch (termios_p->c_cflag & CSIZE)
144     {
145     case CS5:
146       buf.c_cflag |= _SYSV_CS5;
147       break;
148     case CS6:
149       buf.c_cflag |= _SYSV_CS6;
150       break;
151     case CS7:
152       buf.c_cflag |= _SYSV_CS7;
153       break;
154     case CS8:
155       buf.c_cflag |= _SYSV_CS8;
156       break;
157     }
158
159   buf.c_lflag = 0;
160   if (termios_p->c_lflag & ISIG)
161     buf.c_lflag |= _SYSV_ISIG;
162   if (termios_p->c_lflag & ICANON)
163     buf.c_lflag |= _SYSV_ICANON;
164   if (termios_p->c_lflag & ECHO)
165     buf.c_lflag |= _SYSV_ECHO;
166   if (termios_p->c_lflag & ECHOE)
167     buf.c_lflag |= _SYSV_ECHOE;
168   if (termios_p->c_lflag & ECHOK)
169     buf.c_lflag |= _SYSV_ECHOK;
170   if (termios_p->c_lflag & ECHONL)
171     buf.c_lflag |= _SYSV_ECHONL;
172   if (termios_p->c_lflag & NOFLSH)
173     buf.c_lflag |= _SYSV_NOFLSH;
174   if (termios_p->c_lflag & TOSTOP)
175     buf.c_lflag |= _SYSV_TOSTOP;
176   if (termios_p->c_lflag & ECHOCTL)
177     buf.c_lflag |= _SYSV_ECHOCTL;
178   if (termios_p->c_lflag & ECHOPRT)
179     buf.c_lflag |= _SYSV_ECHOPRT;
180   if (termios_p->c_lflag & ECHOKE)
181     buf.c_lflag |= _SYSV_ECHOKE;
182   if (termios_p->c_lflag & FLUSHO)
183     buf.c_lflag |= _SYSV_FLUSHO;
184   if (termios_p->c_lflag & PENDIN)
185     buf.c_lflag |= _SYSV_PENDIN;
186   if (termios_p->c_lflag & IEXTEN)
187     buf.c_lflag |= _SYSV_IEXTEN;
188
189   buf.c_cc[_SYSV_VINTR] = termios_p->c_cc[VINTR];
190   buf.c_cc[_SYSV_VQUIT] = termios_p->c_cc[VQUIT];
191   buf.c_cc[_SYSV_VERASE] = termios_p->c_cc[VERASE];
192   buf.c_cc[_SYSV_VKILL] = termios_p->c_cc[VKILL];
193   if (buf.c_lflag & _SYSV_ICANON)
194     {
195       buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF];
196       buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL];
197     }
198   else
199     {
200       buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN];
201       buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME];
202     }
203   buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2];
204
205   if (__ioctl (fd, ioctl_function, &buf) < 0)
206     return -1;
207   return 0;
208 }