Fix emulator core and UI on Windows

There are two parts in this CL:
1. Fixing the Windows build (missing set_fd_handler)
2. Replacing read/write with socket_recv/socket_send.

Change-Id: I5fa599774260257d481b738a892e1124135fc319
diff --git a/android/async-utils.c b/android/async-utils.c
index 678b0b4..a66e32f 100644
--- a/android/async-utils.c
+++ b/android/async-utils.c
@@ -40,7 +40,7 @@
     }
 
     do {
-        ret = read(io->fd, ar->buffer + ar->pos, ar->buffsize - ar->pos);
+        ret = socket_recv(io->fd, ar->buffer + ar->pos, ar->buffsize - ar->pos);
         if (ret == 0) {
             /* disconnection ! */
             errno = ECONNRESET;
@@ -87,7 +87,7 @@
     }
 
     do {
-        ret = write(io->fd, aw->buffer + aw->pos, aw->buffsize - aw->pos);
+        ret = socket_send(io->fd, aw->buffer + aw->pos, aw->buffsize - aw->pos);
         if (ret == 0) {
             /* disconnection ! */
             errno = ECONNRESET;
@@ -136,7 +136,7 @@
 
     do {
         char ch;
-        ret = read(io->fd, &ch, 1);
+        ret = socket_recv(io->fd, &ch, 1);
         if (ret == 0) {
             /* disconnection ! */
             errno = ECONNRESET;
@@ -247,7 +247,7 @@
         /* We need to read the socket error to determine if
             * the connection was really succesful or not. This
             * is optional, because in case of error a future
-            * read() or write() will fail anyway, but this
+            * socket_recv() or socket_send() will fail anyway, but this
             * allows us to get a better error value as soon as
             * possible.
             */
diff --git a/android/main-ui.c b/android/main-ui.c
index daf71cb..9e511c7 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -502,6 +502,10 @@
         exit(1);
     }
 
+#ifdef _WIN32
+    socket_init();
+#endif
+
     // Lets see if user just wants to list core process.
     if (opts->list_cores) {
         fprintf(stdout, "Enumerating running core processes.\n");
diff --git a/android/protocol/fb-updates-impl.c b/android/protocol/fb-updates-impl.c
index fa4b304..dde79c1 100644
--- a/android/protocol/fb-updates-impl.c
+++ b/android/protocol/fb-updates-impl.c
@@ -113,8 +113,8 @@
     // Read updates while they are immediately available.
     for (;;) {
         // Read next chunk of data.
-        ret = read(fbi->sock, fbi->reader_buffer + fbi->reader_offset,
-                   fbi->reader_bytes - fbi->reader_offset);
+        ret = socket_recv(fbi->sock, fbi->reader_buffer + fbi->reader_offset,
+                          fbi->reader_bytes - fbi->reader_offset);
         if (ret == 0) {
             /* disconnection ! */
             fbUpdatesImpl_destroy();
diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c
index e933d57..2ceeca1 100644
--- a/android/protocol/ui-commands-impl.c
+++ b/android/protocol/ui-commands-impl.c
@@ -124,8 +124,9 @@
     // Read requests while they are immediately available.
     for (;;) {
         // Read next chunk of data.
-        status = read(uicmd->sock, uicmd->reader_buffer + uicmd->reader_offset,
-                      uicmd->reader_bytes - uicmd->reader_offset);
+        status = socket_recv(uicmd->sock,
+                             uicmd->reader_buffer + uicmd->reader_offset,
+                             uicmd->reader_bytes - uicmd->reader_offset);
         if (status == 0) {
             /* Disconnection, meaning that the core process got terminated. */
             fprintf(stderr, "core-ui-control service got disconnected\n");
diff --git a/android/sync-utils.c b/android/sync-utils.c
index 6d3cea6..617ba8b 100644
--- a/android/sync-utils.c
+++ b/android/sync-utils.c
@@ -74,6 +74,7 @@
             connect_status = iolooper_wait(looper, timeout);
             if (connect_status > 0) {
                 iolooper_del_write(looper, fd);
+                break;
             } else {
                 iolooper_free(looper);
                 return NULL;
@@ -184,7 +185,7 @@
             return -1;
         }
         do {
-            ret = read(ssocket->fd, buf, size);
+            ret = socket_recv(ssocket->fd, buf, size);
         } while( ret < 0 && errno == EINTR);
     } else if (ret == 0) {
         // Timed out
@@ -229,7 +230,7 @@
         }
 
         do {
-            ret = write(ssocket->fd, (const char*)buf + written, size - written);
+            ret = socket_send(ssocket->fd, (const char*)buf + written, size - written);
         } while( ret < 0 && errno == EINTR);
 
         if (ret > 0) {
diff --git a/vl-android-ui.c b/vl-android-ui.c
index 6c0c934..0b63d4a 100644
--- a/vl-android-ui.c
+++ b/vl-android-ui.c
@@ -27,7 +27,14 @@
 #define _GNU_SOURCE 1
 #endif
 
+#ifndef _WIN32
 #include <sys/wait.h>
+#endif  // _WIN32
+
+#ifdef _WIN32
+#include <windows.h>
+#include <sys/timeb.h>
+#endif
 
 #include "qemu-common.h"
 #include "net.h"
@@ -54,6 +61,90 @@
 static Looper*  mainLooper;
 
 /***********************************************************/
+/* I/O handling */
+
+typedef struct IOHandlerRecord {
+    LoopIo  io[1];
+    IOHandler* fd_read;
+    IOHandler* fd_write;
+    int        running;
+    int        deleted;
+    void*      opaque;
+    struct IOHandlerRecord *next;
+} IOHandlerRecord;
+
+static IOHandlerRecord *first_io_handler;
+
+static void ioh_callback(void* opaque, int fd, unsigned events)
+{
+    IOHandlerRecord* ioh = opaque;
+    ioh->running = 1;
+    if ((events & LOOP_IO_READ) != 0) {
+        ioh->fd_read(ioh->opaque);
+    }
+    if (!ioh->deleted && (events & LOOP_IO_WRITE) != 0) {
+        ioh->fd_write(ioh->opaque);
+    }
+    ioh->running = 0;
+    if (ioh->deleted) {
+        loopIo_done(ioh->io);
+        free(ioh);
+    }
+}
+
+int qemu_set_fd_handler(int fd,
+                        IOHandler *fd_read,
+                        IOHandler *fd_write,
+                        void *opaque)
+{
+    IOHandlerRecord **pioh, *ioh;
+
+    if (!fd_read && !fd_write) {
+        pioh = &first_io_handler;
+        for(;;) {
+            ioh = *pioh;
+            if (ioh == NULL)
+                return 0;
+            if (ioh->io->fd == fd) {
+                break;
+            }
+            pioh = &ioh->next;
+        }
+        if (ioh->running) {
+            ioh->deleted = 1;
+        } else {
+            *pioh = ioh->next;
+            loopIo_done(ioh->io);
+            free(ioh);
+        }
+    } else {
+        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+            if (ioh->io->fd == fd)
+                goto found;
+        }
+        ANEW0(ioh);
+        ioh->next = first_io_handler;
+        first_io_handler = ioh;
+        loopIo_init(ioh->io, mainLooper, fd, ioh_callback, ioh);
+    found:
+        ioh->fd_read  = fd_read;
+        ioh->fd_write = fd_write;
+        ioh->opaque   = opaque;
+
+        if (fd_read != NULL)
+            loopIo_wantRead(ioh->io);
+        else
+            loopIo_dontWantRead(ioh->io);
+
+        if (fd_write != NULL)
+            loopIo_wantWrite(ioh->io);
+        else
+            loopIo_dontWantWrite(ioh->io);
+    }
+    return 0;
+}
+
+/***********************************************************/
 /* main execution loop */
 
 static LoopTimer  gui_timer[1];