Commit bca52d65cb24542cbe96584d08481a487042a593
1 parent
fbd71bf679
Exists in
master
and in
54 other branches
Initial revision
Showing 1 changed file with 126 additions and 0 deletions Side-by-side Diff
tools/gdb/serial.c
1 | +#include <unistd.h> | |
2 | +#include <string.h> | |
3 | +#include <fcntl.h> | |
4 | +#include <sys/time.h> | |
5 | +#include "serial.h" | |
6 | + | |
7 | +#if defined(__sun__) || \ | |
8 | + defined(__OpenBSD__) || \ | |
9 | + defined(__FreeBSD__) || \ | |
10 | + defined(__NetBSD__) || \ | |
11 | + defined(__APPLE__) | |
12 | +static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } }; | |
13 | +#else | |
14 | +static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 }; | |
15 | +#endif | |
16 | + | |
17 | +static struct speedmap { | |
18 | + char *str; | |
19 | + speed_t val; | |
20 | +} speedmap[] = { | |
21 | + { "50", B50 }, { "75", B75 }, { "110", B110 }, | |
22 | + { "134", B134 }, { "150", B150 }, { "200", B200 }, | |
23 | + { "300", B300 }, { "600", B600 }, { "1200", B1200 }, | |
24 | + { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, | |
25 | + { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 }, | |
26 | + { "57600", B57600 }, | |
27 | +#ifdef B76800 | |
28 | + { "76800", B76800 }, | |
29 | +#endif | |
30 | + { "115200", B115200 }, | |
31 | +#ifdef B153600 | |
32 | + { "153600", B153600 }, | |
33 | +#endif | |
34 | + { "230400", B230400 }, | |
35 | +#ifdef B307200 | |
36 | + { "307200", B307200 }, | |
37 | +#endif | |
38 | +#ifdef B460800 | |
39 | + { "460800", B460800 } | |
40 | +#endif | |
41 | +}; | |
42 | +static int nspeeds = sizeof speedmap / sizeof speedmap[0]; | |
43 | + | |
44 | +speed_t | |
45 | +cvtspeed(char *str) | |
46 | +{ | |
47 | + struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds]; | |
48 | + | |
49 | + while (smp < esmp) { | |
50 | + if (strcmp(str, smp->str) == 0) | |
51 | + return (smp->val); | |
52 | + smp++; | |
53 | + } | |
54 | + return B0; | |
55 | +} | |
56 | + | |
57 | +int | |
58 | +serialopen(char *device, speed_t speed) | |
59 | +{ | |
60 | + int fd; | |
61 | + | |
62 | + if (cfsetospeed(&tios, speed) < 0) | |
63 | + return -1; | |
64 | + | |
65 | + if ((fd = open(device, O_RDWR)) < 0) | |
66 | + return -1; | |
67 | + | |
68 | + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { | |
69 | + (void)close(fd); | |
70 | + return -1; | |
71 | + } | |
72 | + | |
73 | + return fd; | |
74 | +} | |
75 | + | |
76 | +int | |
77 | +serialreadchar(int fd, int timeout) | |
78 | +{ | |
79 | + fd_set fds; | |
80 | + struct timeval tv; | |
81 | + int n; | |
82 | + char ch; | |
83 | + | |
84 | + tv.tv_sec = timeout; | |
85 | + tv.tv_usec = 0; | |
86 | + | |
87 | + FD_ZERO(&fds); | |
88 | + FD_SET(fd, &fds); | |
89 | + | |
90 | + /* this is a fucking horrible quick hack - fix this */ | |
91 | + | |
92 | + if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0) | |
93 | + return SERIAL_ERROR; | |
94 | + | |
95 | + if (n == 0) | |
96 | + return SERIAL_TIMEOUT; | |
97 | + | |
98 | + if ((n = read(fd, &ch, 1)) < 0) | |
99 | + return SERIAL_ERROR; | |
100 | + | |
101 | + if (n == 0) | |
102 | + return SERIAL_EOF; | |
103 | + | |
104 | + return ch; | |
105 | +} | |
106 | + | |
107 | +int | |
108 | +serialwrite(int fd, char *buf, int len) | |
109 | +{ | |
110 | + int n; | |
111 | + | |
112 | + do { | |
113 | + n = write(fd, buf, len); | |
114 | + if (n < 0) | |
115 | + return 1; | |
116 | + len -= n; | |
117 | + buf += n; | |
118 | + } while (len > 0); | |
119 | + return 0; | |
120 | +} | |
121 | + | |
122 | +int | |
123 | +serialclose(int fd) | |
124 | +{ | |
125 | + return close(fd); | |
126 | +} |