Submit merged

Squashed commit of the following:

commit aeefab810c6331e2f96e81f20e4408b39dd3a2ca
Author: Vladimir Chtchetkine <vchtchetkine@google.com>
Date:   Thu Dec 2 07:40:34 2010 -0800

    Implement -attach-core UI option

    Change-Id: I4168e2d707cab1b4873ee16d86d5126c1a316abf

Change-Id: I2da1ef5d53641f3c60d83d8d5ddf3aff34b0c6c7
diff --git a/android/sync-utils.c b/android/sync-utils.c
index 1695615..8d55823 100644
--- a/android/sync-utils.c
+++ b/android/sync-utils.c
@@ -130,6 +130,28 @@
 }
 
 int
+syncsocket_start_write(SyncSocket* ssocket)
+{
+    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+    iolooper_add_write(ssocket->iolooper, ssocket->fd);
+    return 0;
+}
+
+int
+syncsocket_stop_write(SyncSocket* ssocket)
+{
+    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+    iolooper_del_write(ssocket->iolooper, ssocket->fd);
+    return 0;
+}
+
+ssize_t
 syncsocket_read_absolute(SyncSocket* ssocket,
                          void* buf,
                          size_t size,
@@ -151,17 +173,74 @@
         do {
             ret = read(ssocket->fd, buf, size);
         } while( ret < 0 && errno == EINTR);
+    } else if (ret == 0) {
+        // Timed out
+        errno = ETIMEDOUT;
+        ret = -1;
     }
     return ret;
 }
 
-int
+ssize_t
 syncsocket_read(SyncSocket* ssocket, void* buf, size_t size, int timeout)
 {
     return syncsocket_read_absolute(ssocket, buf, size, iolooper_now() + timeout);
 }
 
-int
+ssize_t
+syncsocket_write_absolute(SyncSocket* ssocket,
+                          const void* buf,
+                          size_t size,
+                          int64_t deadline)
+{
+    int ret;
+    size_t written = 0;
+
+    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    do {
+        ret = iolooper_wait_absolute(ssocket->iolooper, deadline);
+        if (ret < 0) {
+            return ret;
+        } else if (ret == 0) {
+            // Timeout.
+            errno = ETIMEDOUT;
+            return -1;
+        }
+        if (!iolooper_is_write(ssocket->iolooper, ssocket->fd)) {
+            D("%s: Internal error, iolooper_is_write() not set!", __FUNCTION__);
+            return -1;
+        }
+
+        do {
+            ret = write(ssocket->fd, (const char*)buf + written, size - written);
+        } while( ret < 0 && errno == EINTR);
+
+        if (ret > 0) {
+            written += ret;
+        } else if (ret < 0) {
+            if (errno != EAGAIN && errno != EWOULDBLOCK) {
+                return -1;
+            }
+        } else {
+            // Disconnected.
+            errno = ECONNRESET;
+            return -1;
+        }
+    } while (written < size);
+    return (int)written;
+}
+
+ssize_t
+syncsocket_write(SyncSocket* ssocket, const void* buf, size_t size, int timeout)
+{
+    return syncsocket_write_absolute(ssocket, buf, size, iolooper_now() + timeout);
+}
+
+ssize_t
 syncsocket_read_line_absolute(SyncSocket* ssocket,
                               char* buffer,
                               size_t size,
@@ -177,7 +256,7 @@
         }
         buffer[read_chars++] = ch;
         if (ch == '\n') {
-            return (int)read_chars;
+            return read_chars;
         }
     }
 
@@ -186,7 +265,7 @@
     return -1;
 }
 
-int
+ssize_t
 syncsocket_read_line(SyncSocket* ssocket, char* buffer, size_t size, int timeout)
 {
     return syncsocket_read_line_absolute(ssocket, buffer, size,