]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/speed.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / speed.c
CommitLineData
d2f5be2a 1/* `struct termios' speed frobnication functions. Linux version.
688903eb 2 Copyright (C) 1991-2018 Free Software Foundation, Inc.
478b92f0
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
478b92f0
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
478b92f0 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
d2f5be2a
UD
18
19#include <stddef.h>
20#include <errno.h>
21#include <termios.h>
22
d2f5be2a 23
a94b2ac0
UD
24/* This is a gross hack around a kernel bug. If the cfsetispeed functions
25 is called with the SPEED argument set to zero this means use the same
26 speed as for output. But we don't have independent input and output
27 speeds and therefore cannot record this.
28
29 We use an unused bit in the `c_iflag' field to keep track of this
30 use of `cfsetispeed'. The value here must correspond to the one used
31 in `tcsetattr.c'. */
32#define IBAUD0 020000000000
33
34
d2f5be2a
UD
35/* Return the output baud rate stored in *TERMIOS_P. */
36speed_t
bd2260a2 37cfgetospeed (const struct termios *termios_p)
d2f5be2a 38{
d41c6f61 39 return termios_p->c_cflag & (CBAUD | CBAUDEX);
d2f5be2a
UD
40}
41
42/* Return the input baud rate stored in *TERMIOS_P.
a94b2ac0
UD
43 Although for Linux there is no difference between input and output
44 speed, the numerical 0 is a special case for the input baud rate. It
45 should set the input baud rate to the output baud rate. */
46speed_t
bd2260a2 47cfgetispeed (const struct termios *termios_p)
a94b2ac0
UD
48{
49 return ((termios_p->c_iflag & IBAUD0)
50 ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX));
51}
d2f5be2a
UD
52
53/* Set the output baud rate stored in *TERMIOS_P to SPEED. */
54int
bd2260a2 55cfsetospeed (struct termios *termios_p, speed_t speed)
d2f5be2a 56{
d41c6f61 57 if ((speed & ~CBAUD) != 0
6999d70e 58 && (speed < B57600 || speed > __MAX_BAUD))
2caca60d 59 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
d2f5be2a 60
416be7f0 61#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
eb35b097 62 termios_p->c_ospeed = speed;
416be7f0 63#endif
d41c6f61
UD
64 termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
65 termios_p->c_cflag |= speed;
d2f5be2a 66
d41c6f61 67 return 0;
d2f5be2a 68}
df962917
RM
69libc_hidden_def (cfsetospeed)
70
d2f5be2a
UD
71
72/* Set the input baud rate stored in *TERMIOS_P to SPEED.
5470bc9f
UD
73 Although for Linux there is no difference between input and output
74 speed, the numerical 0 is a special case for the input baud rate. It
75 should set the input baud rate to the output baud rate. */
76int
bd2260a2 77cfsetispeed (struct termios *termios_p, speed_t speed)
5470bc9f
UD
78{
79 if ((speed & ~CBAUD) != 0
6999d70e 80 && (speed < B57600 || speed > __MAX_BAUD))
2caca60d 81 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
5470bc9f 82
416be7f0 83#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
eb35b097 84 termios_p->c_ispeed = speed;
416be7f0 85#endif
a94b2ac0
UD
86 if (speed == 0)
87 termios_p->c_iflag |= IBAUD0;
88 else
5470bc9f 89 {
a94b2ac0 90 termios_p->c_iflag &= ~IBAUD0;
5470bc9f
UD
91 termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
92 termios_p->c_cflag |= speed;
93 }
94
95 return 0;
96}
df962917 97libc_hidden_def (cfsetispeed)