7 #include <sys/select.h>
13 static int baud_id(int baud);
15 int ser_open(const char *port, int baud, unsigned int mode)
20 if((baud = baud_id(baud)) == -1) {
21 fprintf(stderr, "ser_open: invalid baud number: %d\n", baud);
25 if((fd = open(port, O_RDWR | O_NOCTTY)) == -1) {
36 term.c_cflag = CLOCAL | CREAD | CS8 | HUPCL;
38 term.c_cflag |= CSTOPB;
40 if(mode & SER_HWFLOW) {
41 term.c_cflag |= CRTSCTS;
44 term.c_iflag = IGNBRK | IGNPAR;
46 cfsetispeed(&term, baud);
47 cfsetospeed(&term, baud);
49 if(tcsetattr(fd, TCSANOW, &term) < 0) {
50 fprintf(stderr, "ser_open: failed to set terminal attributes\n");
56 /* assert DTR/RTS lines */
59 if(ioctl(fd, TIOCMGET, &st) == -1) {
60 perror("ser_open: failed to get modem status");
64 st |= TIOCM_DTR | TIOCM_RTS;
65 if(ioctl(fd, TIOCMSET, &st) == -1) {
66 perror("ser_open: failed to set flow control");
76 void ser_close(int fd)
83 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
86 int ser_nonblock(int fd)
88 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
91 int ser_pending(int fd)
93 static struct timeval tv_zero;
99 while(select(fd + 1, &rd, 0, 0, &tv_zero) == -1 && errno == EINTR);
100 return FD_ISSET(fd, &rd);
103 int ser_wait(int fd, long msec)
105 struct timeval tv, tv0;
111 tv.tv_sec = msec / 1000;
112 tv.tv_usec = msec * 1000;
114 gettimeofday(&tv0, 0);
116 while(select(fd + 1, &rd, 0, 0, msec >= 0 ? &tv : 0) == -1 && errno == EINTR) {
117 /* interrupted, recalc timeout and go back to sleep */
119 gettimeofday(&tv, 0);
120 msec -= (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
121 if(msec < 0) msec = 0;
123 tv.tv_sec = msec / 1000;
124 tv.tv_usec = msec * 1000;
128 return FD_ISSET(fd, &rd);
131 int ser_write(int fd, const char *buf, int count)
133 return write(fd, buf, count);
136 int ser_read(int fd, char *buf, int count)
138 return read(fd, buf, count);
141 void ser_printf(int fd, const char *fmt, ...)
146 vdprintf(fd, fmt, ap);
150 char *ser_getline(int fd, char *buf, int bsz)
152 static char linebuf[512];
154 int i, rd, size, offs;
156 size = sizeof linebuf - widx;
157 while(size && (rd = read(fd, linebuf + widx, size)) > 0) {
164 for(i=0; i<widx; i++) {
165 if(linebuf[i] == '\r' || linebuf[i] == '\n') {
166 size = i >= bsz ? bsz - 1 : i;
167 memcpy(buf, linebuf, size);
171 memmove(linebuf, linebuf + offs, widx - offs);
179 static int baud_id(int baud)
184 case 110: return B110;
185 case 134: return B134;
186 case 150: return B150;
187 case 200: return B200;
188 case 300: return B300;
189 case 600: return B600;
190 case 1200: return B1200;
191 case 1800: return B1800;
192 case 2400: return B2400;
193 case 4800: return B4800;
194 case 9600: return B9600;
195 case 19200: return B19200;
196 case 38400: return B38400;
197 case 57600: return B57600;
198 case 115200: return B115200;