Last change caused infinite loops because of missing loop increment.
[glibc.git] / sysdeps / unix / sysv / tcsetattr.c
blobd39ac76a3984e62311d336594f45d1d3d19050fa
1 /* Copyright (C) 1992, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
19 #include <errno.h>
20 #include <stddef.h>
21 #include <termios.h>
22 #include <sys/ioctl.h>
24 #include <sysv_termio.h>
27 const speed_t __unix_speeds[] =
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,
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;
55 struct __sysv_termio buf;
56 int ioctl_function;
57 size_t i;
59 if (termios_p == NULL)
61 __set_errno (EINVAL);
62 return -1;
64 switch (optional_actions)
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;
80 if (termios_p->__ispeed != termios_p->__ospeed)
82 __set_errno (EINVAL);
83 return -1;
85 buf.c_cflag = -1;
86 for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i)
88 if (__unix_speeds[i] == termios_p->__ispeed)
89 buf.c_cflag = i;
91 if (buf.c_cflag == -1)
93 __set_errno (EINVAL);
94 return -1;
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;
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;
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)
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;
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;
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)
196 buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF];
197 buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL];
199 else
201 buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN];
202 buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME];
204 buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2];
206 if (__ioctl (fd, ioctl_function, &buf) < 0)
207 return -1;
208 return 0;
210 libc_hidden_def (tcsetattr)