1 /*
2  * Copyright (C) 2020-2021 Alibaba Group Holding Limited
3  * A modified version of termios in Haiku OS
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #ifndef _SYS_TERMIOS_H_
8 #define _SYS_TERMIOS_H_
9 
10 #include <errno.h>
11 
12 typedef unsigned long tcflag_t;
13 typedef unsigned long speed_t;
14 typedef unsigned char cc_t;
15 
16 #define NCCS    12          /* number of control characters */
17 
18 struct termios {
19     tcflag_t    c_iflag;    /* input modes */
20     tcflag_t    c_oflag;    /* output modes */
21     tcflag_t    c_cflag;    /* control modes */
22     tcflag_t    c_lflag;    /* local modes */
23     cc_t        c_cc[NCCS]; /* control characters */
24 };
25 
26 /* control characters */
27 #define VINTR   0
28 #define VQUIT   1
29 #define VERASE  2
30 #define VKILL   3
31 #define VEOF    4
32 #define VEOL    5
33 #define VMIN    6
34 #define VTIME   7
35 #define VEOL2   8
36 #define VSTART  9
37 #define VSTOP   10
38 #define VSUSP   11
39 
40 /* c_iflag - input control modes */
41 #define IGNBRK      0x0001      /* ignore break condition */
42 #define BRKINT      0x0002      /* break sends interrupt */
43 #define IGNPAR      0x0004      /* ignore characters with parity errors */
44 #define PARMRK      0x0008      /* mark parity errors */
45 #define INPCK       0x0010      /* enable input parity checking */
46 #define ISTRIP      0x0020      /* strip high bit from characters */
47 #define INLCR       0x0040      /* maps newline to CR on input */
48 #define IGNCR       0x0080      /* ignore carriage returns */
49 #define ICRNL       0x0100      /* map CR to newline on input */
50 #define IUCLC       0x0200      /* map all upper case to lower */
51 #define IXON        0x0400      /* enable input SW flow control */
52 #define IXANY       0x0800      /* any character will restart input */
53 #define IXOFF       0x1000      /* enable output SW flow control */
54 
55 /* c_oflag - output control modes */
56 #define OPOST       0x0001      /* enable postprocessing of output */
57 #define OLCUC       0x0002      /* map lowercase to uppercase */
58 #define ONLCR       0x0004      /* map NL to CR-NL on output */
59 #define OCRNL       0x0008      /* map CR to NL on output */
60 #define ONOCR       0x0010      /* no CR output when at column 0 */
61 #define ONLRET      0x0020      /* newline performs CR function */
62 #define OFILL       0x0040      /* use fill characters for delays */
63 #define OFDEL       0x0080      /* Fills are DEL, otherwise NUL */
64 #define NLDLY       0x0100      /* Newline delays: */
65 #define NL0         0x0000
66 #define NL1         0x0100
67 #define CRDLY       0x0600      /* Carriage return delays: */
68 #define CR0         0x0000
69 #define CR1         0x0200
70 #define CR2         0x0400
71 #define CR3         0x0600
72 #define TABDLY      0x1800      /* Tab delays: */
73 #define TAB0        0x0000
74 #define TAB1        0x0800
75 #define TAB2        0x1000
76 #define TAB3        0x1800
77 #define BSDLY       0x2000      /* Backspace delays: */
78 #define BS0         0x0000
79 #define BS1         0x2000
80 #define VTDLY       0x4000      /* Vertical tab delays: */
81 #define VT0         0x0000
82 #define VT1         0x4000
83 #define FFDLY       0x8000      /* Form feed delays: */
84 #define FF0         0x0000
85 #define FF1         0x8000
86 
87 /* c_cflag - control modes */
88 #define CBAUD       0x1000F         /* line speed definitions */
89 #define B0          0x00            /* hang up */
90 #define B50         0x01            /* 50 baud */
91 #define B75         0x02
92 #define B110        0x03
93 #define B134        0x04
94 #define B150        0x05
95 #define B200        0x06
96 #define B300        0x07
97 #define B600        0x08
98 #define B1200       0x09
99 #define B1800       0x0A
100 #define B2400       0x0B
101 #define B4800       0x0C
102 #define B9600       0x0D
103 #define B19200      0x0E
104 #define B38400      0x0F
105 #define CBAUDEX     0x10000
106 #define B57600      0x10001
107 #define B115200     0x10002
108 #define B230400     0x10003
109 #define B460800     0x10004
110 #define B500000     0x10005
111 #define B576000     0x10006
112 #define B921600     0x10007
113 #define B1000000    0x10008
114 #define B1152000    0x10009
115 #define B1500000    0x1000A
116 #define B2000000    0x1000B
117 #define B2500000    0x1000C
118 #define B3000000    0x1000D
119 #define B3500000    0x1000E
120 #define B4000000    0x1000F
121 #define CSIZE       0x0030          /* character size */
122 #define CS5         0x0000
123 #define CS6         0x0010
124 #define CS7         0x0020
125 #define CS8         0x0030
126 #define CSTOPB      0x0040          /* send 2 stop bits, not 1 */
127 #define CREAD       0x0080          /* enable receiver */
128 #define PARENB      0x0100          /* parity enable */
129 #define PARODD      0x0200          /* odd parity, else even */
130 #define HUPCL       0x0400          /* hangs up on last close */
131 #define CLOCAL      0x0800          /* indicates local line */
132 #define XLOBLK      0x1000          /* block layer output? */
133 #define CTSFLOW     0x2000          /* enable CTS flow */
134 #define RTSFLOW     0x4000          /* enable RTS flow */
135 #define CRTSCTS     (RTSFLOW | CTSFLOW)
136 
137 /* c_lflag - local modes */
138 #define ISIG        0x0001          /* enable signals */
139 #define ICANON      0x0002          /* Canonical input */
140 #define XCASE       0x0004          /* Canonical u/l case */
141 #define ECHO        0x0008          /* Enable echo */
142 #define ECHOE       0x0010          /* Echo erase as bs-sp-bs */
143 #define ECHOK       0x0020          /* Echo nl after kill */
144 #define ECHONL      0x0040          /* Echo nl */
145 #define NOFLSH      0x0080          /* Disable flush after int or quit */
146 #define TOSTOP      0x0100          /* stop bg processes that write to tty */
147 #define IEXTEN      0x0200          /* implementation defined extensions */
148 #define ECHOCTL     0x0400
149 #define ECHOPRT     0x0800
150 #define ECHOKE      0x1000
151 #define FLUSHO      0x2000
152 #define PENDIN      0x4000
153 
154 /* options to tcsetattr() */
155 #define TCSANOW     0x01            /* make change immediate */
156 #define TCSADRAIN   0x02            /* drain output, then change */
157 #define TCSAFLUSH   0x04            /* drain output, flush input */
158 
159 /* actions for tcflow() */
160 #define TCOOFF      0x01            /* suspend output */
161 #define TCOON       0x02            /* restart output */
162 #define TCIOFF      0x04            /* transmit STOP character, intended to stop input data */
163 #define TCION       0x08            /* transmit START character, intended to resume input data */
164 
165 /* values for tcflush() */
166 #define TCIFLUSH    0x01            /* flush pending input */
167 #define TCOFLUSH    0x02            /* flush untransmitted output */
168 #define TCIOFLUSH   0x03            /* flush both */
169 
170 #define cfmakeraw(t) \
171     do { \
172         struct termios *_t = (t); \
173         _t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); \
174         _t->c_oflag &= ~OPOST; \
175         _t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); \
176         _t->c_cflag &= ~(CSIZE | PARENB | PARODD); \
177         _t->c_cflag |= CS8; \
178     } while (0)
179 
180 #define cfsetspeed(t, speed) \
181     ({ \
182         struct termios *_t = (t); \
183         tcflag_t flag; \
184         int ret = 0; \
185         switch (speed) { \
186         case 0: \
187             flag = B0; \
188             break; \
189         case 50: \
190             flag = B50; \
191             break; \
192         case 75: \
193             flag = B75; \
194             break; \
195         case 110: \
196             flag = B110; \
197             break; \
198         case 134: \
199             flag = B134; \
200             break; \
201         case 150: \
202             flag = B150; \
203             break; \
204         case 200: \
205             flag = B200; \
206             break; \
207         case 300: \
208             flag = B300; \
209             break; \
210         case 600: \
211             flag = B600; \
212             break; \
213         case 1200: \
214             flag = B1200; \
215             break; \
216         case 1800: \
217             flag = B1800; \
218             break; \
219         case 2400: \
220             flag = B2400; \
221             break; \
222         case 4800: \
223             flag = B4800; \
224             break; \
225         case 9600: \
226             flag = B9600; \
227             break; \
228         case 19200: \
229             flag = B19200; \
230             break; \
231         case 38400: \
232             flag = B38400; \
233             break; \
234         case 57600: \
235             flag = B57600; \
236             break; \
237         case 115200: \
238             flag = B115200; \
239             break; \
240         case 230400: \
241             flag = B230400; \
242             break; \
243         case 460800: \
244             flag = B460800; \
245             break; \
246         case 500000: \
247             flag = B500000; \
248             break; \
249         case 576000: \
250             flag = B576000; \
251             break; \
252         case 921600: \
253             flag = B921600; \
254             break; \
255         case 1000000: \
256             flag = B1000000; \
257             break; \
258         case 1152000: \
259             flag = B1152000; \
260             break; \
261         case 1500000: \
262             flag = B1500000; \
263             break; \
264         case 2000000: \
265             flag = B2000000; \
266             break; \
267         case 2500000: \
268             flag = B2500000; \
269             break; \
270         case 3000000: \
271             flag = B3000000; \
272             break; \
273         case 3500000: \
274             flag = B3500000; \
275             break; \
276         case 4000000: \
277             flag = B4000000; \
278             break; \
279         default: \
280             ret = -1; \
281             break; \
282         } \
283         if (ret) { \
284             errno = EINVAL; \
285         } else { \
286             _t->c_cflag &= ~CBAUD; \
287             _t->c_cflag |= flag; \
288         } \
289         ret; \
290     })
291 
292 #endif /* _SYS_TERMIOS_H_ */
293