[BZ #4925]
[glibc.git] / sysdeps / unix / bsd / tcsetattr.c
blobfd390cd88fc38b595029059d0bf4963549f43d09
1 /* Copyright (C) 1991, 1993, 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>
23 #include "bsdtty.h"
26 const speed_t __bsd_speeds[] =
29 50,
30 75,
31 110,
32 134,
33 150,
34 200,
35 300,
36 600,
37 1200,
38 1800,
39 2400,
40 4800,
41 9600,
42 19200,
43 38400,
47 /* Set the state of FD to *TERMIOS_P. */
48 int
49 tcsetattr (fd, optional_actions, termios_p)
50 int fd;
51 int optional_actions;
52 const struct termios *termios_p;
54 struct sgttyb buf;
55 struct tchars tchars;
56 struct ltchars ltchars;
57 int local;
58 #ifdef TIOCGETX
59 int extra;
60 #endif
61 size_t i;
63 if (__ioctl (fd, TIOCGETP, &buf) < 0 ||
64 __ioctl (fd, TIOCGETC, &tchars) < 0 ||
65 __ioctl (fd, TIOCGLTC, &ltchars) < 0 ||
66 #ifdef TIOCGETX
67 __ioctl (fd, TIOCGETX, &extra) < 0 ||
68 #endif
69 __ioctl (fd, TIOCLGET, &local) < 0)
70 return -1;
72 if (termios_p == NULL)
74 __set_errno (EINVAL);
75 return -1;
77 switch (optional_actions)
79 case TCSANOW:
80 break;
81 case TCSADRAIN:
82 if (tcdrain (fd) < 0)
83 return -1;
84 break;
85 case TCSAFLUSH:
86 if (tcflush (fd, TCIFLUSH) < 0)
87 return -1;
88 break;
89 default:
90 __set_errno (EINVAL);
91 return -1;
94 buf.sg_ispeed = buf.sg_ospeed = -1;
95 for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i)
97 if (__bsd_speeds[i] == termios_p->__ispeed)
98 buf.sg_ispeed = i;
99 if (__bsd_speeds[i] == termios_p->__ospeed)
100 buf.sg_ospeed = i;
102 if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1)
104 __set_errno (EINVAL);
105 return -1;
108 buf.sg_flags &= ~(CBREAK|RAW);
109 if (!(termios_p->c_lflag & ICANON))
110 buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW;
111 #ifdef LPASS8
112 if (termios_p->c_oflag & CS8)
113 local |= LPASS8;
114 else
115 local &= ~LPASS8;
116 #endif
117 if (termios_p->c_lflag & _NOFLSH)
118 local |= LNOFLSH;
119 else
120 local &= ~LNOFLSH;
121 if (termios_p->c_oflag & OPOST)
122 local &= ~LLITOUT;
123 else
124 local |= LLITOUT;
125 #ifdef TIOCGETX
126 if (termios_p->c_lflag & ISIG)
127 extra &= ~NOISIG;
128 else
129 extra |= NOISIG;
130 if (termios_p->c_cflag & CSTOPB)
131 extra |= STOPB;
132 else
133 extra &= ~STOPB;
134 #endif
135 if (termios_p->c_iflag & ICRNL)
136 buf.sg_flags |= CRMOD;
137 else
138 buf.sg_flags &= ~CRMOD;
139 if (termios_p->c_iflag & IXOFF)
140 buf.sg_flags |= TANDEM;
141 else
142 buf.sg_flags &= ~TANDEM;
144 buf.sg_flags &= ~(ODDP|EVENP);
145 if (!(termios_p->c_cflag & PARENB))
146 buf.sg_flags |= ODDP | EVENP;
147 else if (termios_p->c_cflag & PARODD)
148 buf.sg_flags |= ODDP;
149 else
150 buf.sg_flags |= EVENP;
152 if (termios_p->c_lflag & _ECHO)
153 buf.sg_flags |= ECHO;
154 else
155 buf.sg_flags &= ~ECHO;
156 if (termios_p->c_lflag & ECHOE)
157 local |= LCRTERA;
158 else
159 local &= ~LCRTERA;
160 if (termios_p->c_lflag & ECHOK)
161 local |= LCRTKIL;
162 else
163 local &= ~LCRTKIL;
164 if (termios_p->c_lflag & _TOSTOP)
165 local |= LTOSTOP;
166 else
167 local &= ~LTOSTOP;
169 buf.sg_erase = termios_p->c_cc[VERASE];
170 buf.sg_kill = termios_p->c_cc[VKILL];
171 tchars.t_eofc = termios_p->c_cc[VEOF];
172 tchars.t_intrc = termios_p->c_cc[VINTR];
173 tchars.t_quitc = termios_p->c_cc[VQUIT];
174 ltchars.t_suspc = termios_p->c_cc[VSUSP];
175 tchars.t_startc = termios_p->c_cc[VSTART];
176 tchars.t_stopc = termios_p->c_cc[VSTOP];
178 if (__ioctl (fd, TIOCSETP, &buf) < 0 ||
179 __ioctl (fd, TIOCSETC, &tchars) < 0 ||
180 __ioctl (fd, TIOCSLTC, &ltchars) < 0 ||
181 #ifdef TIOCGETX
182 __ioctl (fd, TIOCSETX, &extra) < 0 ||
183 #endif
184 __ioctl (fd, TIOCLSET, &local) < 0)
185 return -1;
186 return 0;
188 libc_hidden_def (tcsetattr)