int fd;
fd = open (devfile, O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (fd == -1)
- return -1;
-
return fd;
}
-void
+int
close_serial (int unix_fd)
{
- close (unix_fd);
+ // Linus writes: do not retry close after EINTR
+ return close (unix_fd);
}
guint32
int
write_serial (int fd, guchar *buffer, int offset, int count, int timeout)
{
- struct timeval tmval;
- fd_set writefs;
+ struct pollfd pinfo;
guint32 n;
- n = count - offset;
+ pinfo.fd = fd;
+ pinfo.events = POLLOUT;
+ pinfo.revents = POLLOUT;
+
+ n = count;
- FD_SET(fd, &writefs);
- tmval.tv_sec = timeout / 1000;
- tmval.tv_usec = (timeout - tmval.tv_sec) * 1000;
-
while (n > 0)
{
size_t t;
- if (timeout > 0)
- {
- if (select(fd+1, NULL, &writefs, NULL, &tmval) <= 0 && errno != EINTR)
- {
+ if (timeout != 0) {
+ int c;
+
+ while ((c = poll (&pinfo, 1, timeout)) == -1 && errno == EINTR)
+ ;
+ if (c == -1)
return -1;
- }
}
- t = write(fd, buffer + offset, count);
-
- if (timeout > 0)
- {
- if (select(fd+1, NULL, &writefs, NULL, &tmval) <= 0 && errno != EINTR)
- {
- return -1;
- }
- }
+ do {
+ t = write (fd, buffer + offset, n);
+ } while (t == -1 && errno == EINTR);
+ if (t < 0)
+ return -1;
+
offset += t;
n -= t;
}
return 0;
}
-void
+int
discard_buffer (int fd, gboolean input)
{
- tcflush(fd, input ? TCIFLUSH : TCOFLUSH);
+ return tcflush(fd, input ? TCIFLUSH : TCOFLUSH);
}
gint32
{
struct termios newtio;
- tcgetattr (fd, &newtio);
+ if (tcgetattr (fd, &newtio) == -1)
+ return FALSE;
+
newtio.c_cflag |= (CLOCAL | CREAD);
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | IEXTEN );
newtio.c_oflag &= ~(OPOST);
/* setup baudrate */
switch (baud_rate)
{
+/*Some values are not defined on OSX and *BSD */
+#if defined(B921600)
+ case 921600:
+ baud_rate = B921600;
+ break;
+#endif
+#if defined(B460800)
+ case 460800:
+ baud_rate = B460800;
+ break;
+#endif
case 230400:
baud_rate = B230400;
break;
case Even: /* Even */
newtio.c_cflag &= ~(PARODD);
+ newtio.c_cflag |= (PARENB);
break;
case Mark: /* Mark */
return 1;
}
+int
+breakprop (int fd)
+{
+ return tcsendbreak (fd, 0);
+}
+
gboolean
poll_serial (int fd, gint32 *error, int timeout)
{