Add android/utils/eintr_wrapper.h

Add a new Android-specific header that defines two macros to
handle EINTR in a consistent way, as well as allow detecting
when a system call loops too many times and exit with a fatal
error message when that happens.

+ Unit tests.

+ Update existing code under android/ which uses to deal directly
  with EINTR to use the new HANDLE_EINTR() and IGNORE_EINTR()

+ Remove EINTR checks for functions that call socket_xxx() functions
  which already loop around EINTR.

Change-Id: I1d2ee64d9743a2edc506f616465ea091878db620
diff --git a/android/async-socket.c b/android/async-socket.c
index 92c2ef7..107cdbb 100644
--- a/android/async-socket.c
+++ b/android/async-socket.c
@@ -20,10 +20,11 @@
  * a TCP port forwarding, enabled by ADB.
  */
 
-#include "android/utils/debug.h"
 #include "android/async-socket-connector.h"
 #include "android/async-socket.h"
-#include "utils/panic.h"
+#include "android/utils/debug.h"
+#include "android/utils/eintr_wrapper.h"
+#include "android/utils/panic.h"
 #include "android/iolooper.h"
 
 #define  E(...)    derror(__VA_ARGS__)
@@ -827,13 +828,10 @@
     }
 
     /* Read next chunk of data. */
-    int res = socket_recv(as->fd, asr->buffer + asr->transferred,
-                          asr->to_transfer - asr->transferred);
-    while (res < 0 && errno == EINTR) {
-        res = socket_recv(as->fd, asr->buffer + asr->transferred,
-                          asr->to_transfer - asr->transferred);
-    }
-
+    int res = HANDLE_EINTR(
+            socket_recv(as->fd,
+                        asr->buffer + asr->transferred,
+                        asr->to_transfer - asr->transferred));
     if (res == 0) {
         /* Socket has been disconnected. */
         errno = ECONNRESET;
@@ -937,13 +935,10 @@
     }
 
     /* Write next chunk of data. */
-    int res = socket_send(as->fd, asw->buffer + asw->transferred,
-                          asw->to_transfer - asw->transferred);
-    while (res < 0 && errno == EINTR) {
-        res = socket_send(as->fd, asw->buffer + asw->transferred,
-                          asw->to_transfer - asw->transferred);
-    }
-
+    int res = HANDLE_EINTR(
+            socket_send(as->fd,
+                        asw->buffer + asw->transferred,
+                        asw->to_transfer - asw->transferred));
     if (res == 0) {
         /* Socket has been disconnected. */
         errno = ECONNRESET;