OSDN Git Service

use regular headers rather than trying to get tricky
[uclinux-h8/uClibc.git] / libc / termios / termios.c
1 /* Copyright (C) 1992, 1993, 1996, 1997, 1998 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
20    About the only thing remaining here fromthe original Linux-8086 C library
21    version by Robert de Bath <robert@mayday.compulink.co.uk>, is the general
22    layout.  All else has been recently stolen from GNU libc, since that was
23    much more current.
24  */
25
26 #define tcgetattr __tcgetattr
27
28 #include <errno.h>
29 #include <stddef.h>
30 #include <sys/ioctl.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <termios.h>
34
35 #ifdef L_isatty
36 /* Return 1 if FD is a terminal, 0 if not.  */
37
38 int attribute_hidden __isatty(int fd)
39 {
40     struct termios term;
41     return (tcgetattr (fd, &term) == 0);
42 }
43 strong_alias(__isatty,isatty)
44 #endif
45
46 #ifdef L_tcdrain
47 /* Wait for pending output to be written on FD.  */
48 int __libc_tcdrain (int fd)
49 {
50       /* With an argument of 1, TCSBRK waits for the output to drain.  */
51       return __ioctl(fd, TCSBRK, 1);
52 }
53 weak_alias(__libc_tcdrain, tcdrain)
54 #endif
55
56 #ifdef L_tcflow
57 /* Suspend or restart transmission on FD.  */
58 int tcflow ( int fd, int action)
59 {
60       return __ioctl(fd, TCXONC, action);
61 }
62 #endif
63
64 #ifdef L_tcflush
65 /* Flush pending data on FD.  */
66 int tcflush ( int fd, int queue_selector)
67 {
68       return __ioctl(fd, TCFLSH, queue_selector);
69 }
70 #endif
71
72 #ifdef L_tcsendbreak
73 /* Send zero bits on FD.  */
74 int tcsendbreak( int fd, int duration)
75 {
76         /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
77            and an implementation-defined period if DURATION is nonzero.
78            We define a positive DURATION to be number of milliseconds to break.  */
79         if (duration <= 0)
80                 return __ioctl(fd, TCSBRK, 0);
81
82 #ifdef TCSBRKP
83         /* Probably Linux-specific: a positive third TCSBRKP ioctl argument is
84            defined to be the number of 100ms units to break.  */
85         return __ioctl(fd, TCSBRKP, (duration + 99) / 100);
86 #else
87         /* ioctl can't send a break of any other duration for us.
88            This could be changed to use trickery (e.g. lower speed and
89            send a '\0') to send the break, but for now just return an error.  */
90         __set_errno (EINVAL);
91         return -1;
92 #endif
93 }
94 #endif
95
96 #ifdef L_tcsetpgrp
97 /* Set the foreground process group ID of FD set PGRP_ID.  */
98 int tcsetpgrp ( int fd, pid_t pgrp_id)
99 {
100       return __ioctl (fd, TIOCSPGRP, &pgrp_id);
101 }
102 #endif
103
104 #ifdef L_tcgetpgrp
105 /* Return the foreground process group ID of FD.  */
106 pid_t attribute_hidden __tcgetpgrp ( int fd)
107 {
108     int pgrp;
109
110     if (__ioctl (fd, TIOCGPGRP, &pgrp) < 0)
111         return (pid_t) -1;
112     return (pid_t) pgrp;
113 }
114 strong_alias(__tcgetpgrp,tcgetpgrp)
115 #endif
116
117 /* This is a gross hack around a kernel bug.  If the cfsetispeed functions is
118  * called with the SPEED argument set to zero this means use the same speed as
119  * for output.  But we don't have independent input and output speeds and
120  * therefore cannot record this.
121  *
122  * We use an unused bit in the `c_iflag' field to keep track of this use of
123  * `cfsetispeed'.  The value here must correspond to the one used in
124  * `tcsetattr.c'.  */
125 #define IBAUD0  020000000000
126
127 #ifdef L_cfgetospeed
128 /* Return the output baud rate stored in *TERMIOS_P.  */
129 speed_t cfgetospeed ( const struct termios *termios_p)
130 {
131       return termios_p->c_cflag & (CBAUD | CBAUDEX);
132 }
133 #endif
134
135 #ifdef L_cfgetispeed
136
137 /* Return the input baud rate stored in *TERMIOS_P.
138  * Although for Linux there is no difference between input and output
139  * speed, the numerical 0 is a special case for the input baud rate. It
140  * should set the input baud rate to the output baud rate. */
141 speed_t cfgetispeed (const struct termios *termios_p)
142 {
143     return ((termios_p->c_iflag & IBAUD0)
144             ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX));
145 }
146 #endif
147
148 #ifdef L_cfsetospeed
149 /* Set the output baud rate stored in *TERMIOS_P to SPEED.  */
150 int attribute_hidden __cfsetospeed  (struct termios *termios_p, speed_t speed)
151 {
152     if ((speed & ~CBAUD) != 0
153             && (speed < B57600 || speed > B460800))
154     {
155         __set_errno(EINVAL);
156         return -1;
157     }
158
159     termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
160     termios_p->c_cflag |= speed;
161
162     return 0;
163 }
164 strong_alias(__cfsetospeed,cfsetospeed)
165 #endif
166
167 #ifdef L_cfsetispeed
168 /* Set the input baud rate stored in *TERMIOS_P to SPEED.
169  *    Although for Linux there is no difference between input and output
170  *       speed, the numerical 0 is a special case for the input baud rate.  It
171  *          should set the input baud rate to the output baud rate.  */
172 int attribute_hidden __cfsetispeed ( struct termios *termios_p, speed_t speed)
173 {
174     if ((speed & ~CBAUD) != 0
175             && (speed < B57600 || speed > B460800))
176     {
177         __set_errno(EINVAL);
178         return -1;
179     }
180
181     if (speed == 0)
182         termios_p->c_iflag |= IBAUD0;
183     else
184     {
185         termios_p->c_iflag &= ~IBAUD0;
186         termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
187         termios_p->c_cflag |= speed;
188     }
189
190     return 0;
191 }
192 strong_alias(__cfsetispeed,cfsetispeed)
193 #endif
194
195 #ifdef L_cfsetspeed
196
197 extern int __cfsetospeed (struct termios *__termios_p, speed_t __speed) __THROW attribute_hidden;
198 extern int __cfsetispeed (struct termios *__termios_p, speed_t __speed) __THROW attribute_hidden;
199
200 struct speed_struct
201 {
202   speed_t value;
203   speed_t internal;
204 };
205
206 static const struct speed_struct speeds[] =
207   {
208 #ifdef B0
209     { 0, B0 },
210 #endif
211 #ifdef B50
212     { 50, B50 },
213 #endif
214 #ifdef B75
215     { 75, B75 },
216 #endif
217 #ifdef B110
218     { 110, B110 },
219 #endif
220 #ifdef B134
221     { 134, B134 },
222 #endif
223 #ifdef B150
224     { 150, B150 },
225 #endif
226 #ifdef B200
227     { 200, B200 },
228 #endif
229 #ifdef B300
230     { 300, B300 },
231 #endif
232 #ifdef B600
233     { 600, B600 },
234 #endif
235 #ifdef B1200
236     { 1200, B1200 },
237 #endif
238 #ifdef B1200
239     { 1200, B1200 },
240 #endif
241 #ifdef B1800
242     { 1800, B1800 },
243 #endif
244 #ifdef B2400
245     { 2400, B2400 },
246 #endif
247 #ifdef B4800
248     { 4800, B4800 },
249 #endif
250 #ifdef B9600
251     { 9600, B9600 },
252 #endif
253 #ifdef B19200
254     { 19200, B19200 },
255 #endif
256 #ifdef B38400
257     { 38400, B38400 },
258 #endif
259 #ifdef B57600
260     { 57600, B57600 },
261 #endif
262 #ifdef B76800
263     { 76800, B76800 },
264 #endif
265 #ifdef B115200
266     { 115200, B115200 },
267 #endif
268 #ifdef B153600
269     { 153600, B153600 },
270 #endif
271 #ifdef B230400
272     { 230400, B230400 },
273 #endif
274 #ifdef B307200
275     { 307200, B307200 },
276 #endif
277 #ifdef B460800
278     { 460800, B460800 },
279 #endif
280   };
281
282
283 /* Set both the input and output baud rates stored in *TERMIOS_P to SPEED.  */
284 int cfsetspeed (struct termios *termios_p, speed_t speed)
285 {
286   size_t cnt;
287
288   for (cnt = 0; cnt < sizeof (speeds) / sizeof (speeds[0]); ++cnt)
289     if (speed == speeds[cnt].internal)
290       {
291         __cfsetispeed (termios_p, speed);
292         __cfsetospeed (termios_p, speed);
293         return 0;
294       }
295     else if (speed == speeds[cnt].value)
296       {
297         __cfsetispeed (termios_p, speeds[cnt].internal);
298         __cfsetospeed (termios_p, speeds[cnt].internal);
299         return 0;
300       }
301
302   __set_errno (EINVAL);
303
304   return -1;
305 }
306 #endif
307
308 #ifdef L_cfmakeraw
309 /* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
310    This file is part of the GNU C Library.
311 */
312 #include <termios.h>
313
314 /* Set *T to indicate raw mode.  */
315 void
316 cfmakeraw (struct termios *t)
317 {
318   t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
319   t->c_oflag &= ~OPOST;
320   t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
321   t->c_cflag &= ~(CSIZE|PARENB);
322   t->c_cflag |= CS8;
323   t->c_cc[VMIN] = 1;            /* read returns when one char is available.  */
324   t->c_cc[VTIME] = 0;
325 }
326 #endif
327