#include <sys/syslimits.h>
#endif
#ifdef __linux__
+#ifdef HAVE_LIBUDEV
#include "libudev.h"
+#endif
+#ifndef __ANDROID__
#include "linux/serial.h"
+#endif
#include "linux_termios.h"
+
+/* TCGETX/TCSETX is not available everywhere. */
#if defined(TCGETX) && defined(TCSETX) && defined(HAVE_TERMIOX)
#define USE_TERMIOX
#endif
#endif
+/* TIOCINQ/TIOCOUTQ is not available everywhere. */
+#if !defined(TIOCINQ) && defined(FIONREAD)
+#define TIOCINQ FIONREAD
+#endif
+#if !defined(TIOCOUTQ) && defined(FIONWRITE)
+#define TIOCOUTQ FIONWRITE
+#endif
+
#ifndef _WIN32
#include "linux_termios.h"
#endif
#define RETURN_OK() RETURN_CODE(SP_OK);
#define RETURN_ERROR(err, msg) do { DEBUG_ERROR(err, msg); return err; } while (0)
#define RETURN_FAIL(msg) do { DEBUG_FAIL(msg); return SP_ERR_FAIL; } while (0)
-#define RETURN_VALUE(fmt, x) do { DEBUG("%s returning " fmt, __func__, x); return x; } while (0)
+#define RETURN_VALUE(fmt, x) do { \
+ typeof(x) _x = x; \
+ DEBUG("%s returning " fmt, __func__, _x); \
+ return _x; \
+} while (0)
#define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0)
#define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0)
#define TRACE(fmt, ...) DEBUG("%s(" fmt ") called", __func__, ##__VA_ARGS__)
IOObjectRelease(iter);
out_done:
#endif
-#ifdef __linux__
+#if defined(__linux__) && defined(HAVE_LIBUDEV)
struct udev *ud;
struct udev_enumerate *ud_enumerate;
struct udev_list_entry *ud_list;
#else
int result;
while (1) {
+#ifdef __ANDROID__
+ int arg = 1;
+ result = ioctl(port->fd, TCSBRK, &arg);
+#else
result = tcdrain(port->fd);
+#endif
if (result < 0) {
if (errno == EINTR) {
DEBUG("tcdrain() was interrupted");
RETURN_FAIL("ReadFile() failed");
/* Get number of bytes read. */
- GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
+ if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
+ RETURN_FAIL("GetOverlappedResult() failed");
RETURN_VALUE("%d", bytes_read);
#else