Lely core libraries 2.3.4
attr.c
Go to the documentation of this file.
1
24#include "io.h"
25
26#if !LELY_NO_STDIO
27
28#include <lely/util/errnum.h>
29
30#include <assert.h>
31
32#include "attr.h"
33
34#if _WIN32 || _POSIX_C_SOURCE >= 200112L
35
36int
38{
39 assert(attr);
40
41#if _WIN32
42 return io_attr_lpDCB(attr)->BaudRate;
43#else
44 switch (cfgetospeed((const struct termios *)attr)) {
45 case B0: return 0;
46 case B50: return 50;
47 case B75: return 75;
48 case B110: return 110;
49 case B134: return 134;
50 case B150: return 150;
51 case B200: return 200;
52 case B300: return 300;
53 case B600: return 600;
54 case B1200: return 1200;
55 case B1800: return 1800;
56 case B2400: return 2400;
57 case B4800: return 4800;
58 case B9600: return 9600;
59 case B19200: return 19200;
60 case B38400: return 38400;
61#ifdef B7200
62 case B7200: return 7200;
63#endif
64#ifdef B14400
65 case B14400: return 14400;
66#endif
67#ifdef B57600
68 case B57600: return 57600;
69#endif
70#ifdef B115200
71 case B115200: return 115200;
72#endif
73#ifdef B230400
74 case B230400: return 230400;
75#endif
76#ifdef B460800
77 case B460800: return 460800;
78#endif
79#ifdef B500000
80 case B500000: return 500000;
81#endif
82#ifdef B576000
83 case B576000: return 576000;
84#endif
85#ifdef B921600
86 case B921600: return 921600;
87#endif
88#ifdef B1000000
89 case B1000000: return 1000000;
90#endif
91#ifdef B1152000
92 case B1152000: return 1152000;
93#endif
94#ifdef B2000000
95 case B2000000: return 2000000;
96#endif
97#ifdef B3000000
98 case B3000000: return 3000000;
99#endif
100#ifdef B3500000
101 case B3500000: return 3500000;
102#endif
103#ifdef B4000000
104 case B4000000: return 4000000;
105#endif
106 default: set_errnum(ERRNUM_INVAL); return -1;
107 }
108#endif
109}
110
111int
113{
114 assert(attr);
115
116#if _WIN32
117 io_attr_lpDCB(attr)->BaudRate = speed;
118
119 return 0;
120#else
121 speed_t baud;
122 switch (speed) {
123 case 0: baud = B0; break;
124 case 50: baud = B50; break;
125 case 75: baud = B75; break;
126 case 110: baud = B110; break;
127 case 134: baud = B134; break;
128 case 150: baud = B150; break;
129 case 200: baud = B200; break;
130 case 300: baud = B300; break;
131 case 600: baud = B600; break;
132 case 1200: baud = B1200; break;
133 case 1800: baud = B1800; break;
134 case 2400: baud = B2400; break;
135 case 4800: baud = B4800; break;
136 case 9600: baud = B9600; break;
137 case 19200: baud = B19200; break;
138 case 38400: baud = B38400; break;
139#ifdef B7200
140 case 7200: baud = B7200; break;
141#endif
142#ifdef B14400
143 case 14400: baud = B14400; break;
144#endif
145#ifdef B57600
146 case 57600: baud = B57600; break;
147#endif
148#ifdef B115200
149 case 115200: baud = B115200; break;
150#endif
151#ifdef B230400
152 case 230400: baud = B230400; break;
153#endif
154#ifdef B460800
155 case 460800: baud = B460800; break;
156#endif
157#ifdef B500000
158 case 500000: baud = B500000; break;
159#endif
160#ifdef B576000
161 case 576000: baud = B576000; break;
162#endif
163#ifdef B921600
164 case 921600: baud = B921600; break;
165#endif
166#ifdef B1000000
167 case 1000000: baud = B1000000; break;
168#endif
169#ifdef B1152000
170 case 1152000: baud = B1152000; break;
171#endif
172#ifdef B2000000
173 case 2000000: baud = B2000000; break;
174#endif
175#ifdef B3000000
176 case 3000000: baud = B3000000; break;
177#endif
178#ifdef B3500000
179 case 3500000: baud = B3500000; break;
180#endif
181#ifdef B4000000
182 case 4000000: baud = B4000000; break;
183#endif
184 default: set_errnum(ERRNUM_INVAL); return -1;
185 }
186
187 if (cfsetispeed((struct termios *)attr, baud) == -1)
188 return -1;
189 if (cfsetospeed((struct termios *)attr, baud) == -1)
190 return -1;
191
192 return 0;
193#endif
194}
195
196int
198{
199 assert(attr);
200
201#if _WIN32
202 LPDCB lpDCB = io_attr_lpDCB(attr);
203 return lpDCB->fOutX || lpDCB->fInX;
204#else
205 return !!(((const struct termios *)attr)->c_iflag & (IXOFF | IXON));
206#endif
207}
208
209int
210io_attr_set_flow_control(io_attr_t *attr, int flow_control)
211{
212 assert(attr);
213
214#if _WIN32
215 LPDCB lpDCB = io_attr_lpDCB(attr);
216 lpDCB->fOutxCtsFlow = FALSE;
217 lpDCB->fOutxDsrFlow = FALSE;
218 lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
219 lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
220 if (flow_control) {
221 lpDCB->fOutX = TRUE;
222 lpDCB->fInX = TRUE;
223 } else {
224 lpDCB->fOutX = FALSE;
225 lpDCB->fInX = FALSE;
226 }
227
228 return 0;
229#else
230 struct termios *ios = (struct termios *)attr;
231 if (flow_control)
232 ios->c_iflag |= IXOFF | IXON;
233 else
234 ios->c_iflag &= ~(IXOFF | IXON);
235
236 return 0;
237#endif
238}
239
240int
242{
243 assert(attr);
244
245#if _WIN32
246 switch (io_attr_lpDCB(attr)->Parity) {
247 case EVENPARITY: return IO_PARITY_EVEN;
248 case ODDPARITY: return IO_PARITY_ODD;
249 default: return IO_PARITY_NONE;
250 }
251#else
252 const struct termios *ios = (const struct termios *)attr;
253 if (ios->c_cflag & PARENB)
254 return (ios->c_cflag & PARODD) ? IO_PARITY_ODD : IO_PARITY_EVEN;
255 return IO_PARITY_NONE;
256#endif
257}
258
259int
261{
262 assert(attr);
263
264#if _WIN32
265 LPDCB lpDCB = io_attr_lpDCB(attr);
266 switch (parity) {
267 case IO_PARITY_NONE:
268 lpDCB->fParity = FALSE;
269 lpDCB->Parity = NOPARITY;
270 return 0;
271 case IO_PARITY_ODD:
272 lpDCB->fParity = TRUE;
273 lpDCB->Parity = ODDPARITY;
274 return 0;
275 case IO_PARITY_EVEN:
276 lpDCB->fParity = TRUE;
277 lpDCB->Parity = EVENPARITY;
278 return 0;
279 default: set_errnum(ERRNUM_INVAL); return -1;
280 }
281#else
282 struct termios *ios = (struct termios *)attr;
283 switch (parity) {
284 case IO_PARITY_NONE:
285 ios->c_iflag |= IGNPAR;
286 ios->c_cflag &= ~(PARENB | PARODD);
287 return 0;
288 case IO_PARITY_ODD:
289 ios->c_iflag &= ~(IGNPAR | PARMRK);
290 ios->c_iflag |= INPCK;
291 ios->c_cflag |= PARENB;
292 ios->c_cflag &= ~PARODD;
293 return 0;
294 case IO_PARITY_EVEN:
295 ios->c_iflag &= ~(IGNPAR | PARMRK);
296 ios->c_iflag |= INPCK;
297 ios->c_cflag |= (PARENB | PARODD);
298 return 0;
299 default: set_errnum(ERRNUM_INVAL); return -1;
300 }
301#endif
302}
303
304int
306{
307 assert(attr);
308
309#if _WIN32
310 return io_attr_lpDCB(attr)->StopBits == TWOSTOPBITS;
311#else
312 return !!(((const struct termios *)attr)->c_cflag & CSTOPB);
313#endif
314}
315
316int
317io_attr_set_stop_bits(io_attr_t *attr, int stop_bits)
318{
319 assert(attr);
320
321#if _WIN32
322 LPDCB lpDCB = io_attr_lpDCB(attr);
323 if (stop_bits)
324 lpDCB->StopBits = TWOSTOPBITS;
325 else
326 lpDCB->StopBits = ONESTOPBIT;
327
328 return 0;
329#else
330 struct termios *ios = (struct termios *)attr;
331 if (stop_bits)
332 ios->c_cflag |= CSTOPB;
333 else
334 ios->c_cflag &= ~CSTOPB;
335
336 return 0;
337#endif
338}
339
340int
342{
343 assert(attr);
344
345#if _WIN32
346 return io_attr_lpDCB(attr)->ByteSize;
347#else
348 switch (((const struct termios *)attr)->c_cflag & CSIZE) {
349 case CS5: return 5;
350 case CS6: return 6;
351 case CS7: return 7;
352 case CS8: return 8;
353 default: set_errnum(ERRNUM_INVAL); return -1;
354 }
355#endif
356}
357
358int
359io_attr_set_char_size(io_attr_t *attr, int char_size)
360{
361 assert(attr);
362
363#if _WIN32
364 io_attr_lpDCB(attr)->ByteSize = char_size;
365
366 return 0;
367#else
368 struct termios *ios = (struct termios *)attr;
369 ios->c_cflag &= ~CSIZE;
370 switch (char_size) {
371 case 5: ios->c_cflag |= CS5; return 0;
372 case 6: ios->c_cflag |= CS6; return 0;
373 case 7: ios->c_cflag |= CS7; return 0;
374 case 8: ios->c_cflag |= CS8; return 0;
375 default: set_errnum(ERRNUM_INVAL); return -1;
376 }
377#endif
378}
379
380#endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
381
382#endif // !LELY_NO_STDIO
int io_attr_get_char_size(const io_attr_t *attr)
Obtains the character size (in bits) from the attributes of a serial I/O device.
Definition: attr.c:341
int io_attr_get_flow_control(const io_attr_t *attr)
Checks if flow control is enabled in the attributes of a serial I/O device.
Definition: attr.c:197
int io_attr_set_parity(io_attr_t *attr, int parity)
Sets the parity scheme of a serial I/O device.
Definition: attr.c:260
int io_attr_get_speed(const io_attr_t *attr)
Returns the baud rate from the attributes of a serial I/O device, or -1 on error.
Definition: attr.c:37
int io_attr_set_flow_control(io_attr_t *attr, int flow_control)
Disables flow control for a serial I/O device if flow_control is zero, and enables it otherwise.
Definition: attr.c:210
int io_attr_set_stop_bits(io_attr_t *attr, int stop_bits)
Sets the number of stop bits used in a serial I/O device to one if stop_bits is zero,...
Definition: attr.c:317
int io_attr_set_speed(io_attr_t *attr, int speed)
Sets the baud rate of a serial I/O device.
Definition: attr.c:112
int io_attr_get_parity(const io_attr_t *attr)
Obtains the parity scheme from the attributes of a serial I/O device.
Definition: attr.c:241
int io_attr_get_stop_bits(const io_attr_t *attr)
Obtains the number of stop bits used from the attributes of a serial I/O device.
Definition: attr.c:305
int io_attr_set_char_size(io_attr_t *attr, int char_size)
Sets the character size (in bits) of a serial I/O device.
Definition: attr.c:359
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:132
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
@ IO_PARITY_NONE
No parity.
Definition: attr.h:50
@ IO_PARITY_ODD
Odd parity.
Definition: attr.h:52
@ IO_PARITY_EVEN
Even parity.
Definition: attr.h:54
This is the internal header file of the Windows-specific I/O declarations.
This is the internal header file of the serial I/O attributes declarations.
An opaque serial I/O device attributes type.
Definition: attr.h:34