[virtcon] Make run-vc agnostic to fdio implementation

Bug: US-534 #done
Bug: ZX-2680 #done
Test: Check that run-vc works
Change-Id: Icb733697aa5b1f10acca57503e40d6d969dd12c4
diff --git a/system/core/virtcon/main.cpp b/system/core/virtcon/main.cpp
index 3babc53..823b9ef 100644
--- a/system/core/virtcon/main.cpp
+++ b/system/core/virtcon/main.cpp
@@ -236,10 +236,8 @@
     zx_handle_t handles[FDIO_MAX_HANDLES];
     uint32_t types[FDIO_MAX_HANDLES];
     zx_status_t r = fdio_transfer_fd(fd, FDIO_FLAG_USE_FOR_STDIO | 0, handles, types);
-    if (r != 2) {
-        zx_handle_close_many(handles, r);
-        session_destroy(vc);
-    } else if (zx_channel_write(h, 0, types, 2 * sizeof(uint32_t), handles, 2) != ZX_OK) {
+    if (zx_channel_write(h, 0, types,
+                         static_cast<uint32_t>(r * sizeof(uint32_t)), handles, r) != ZX_OK) {
         session_destroy(vc);
     } else {
         port_wait(&port, &vc->fh.ph);
diff --git a/system/uapp/run-vc/main.c b/system/uapp/run-vc/main.c
index 6c4ba8a..2636b13 100644
--- a/system/uapp/run-vc/main.c
+++ b/system/uapp/run-vc/main.c
@@ -43,13 +43,14 @@
     zx_object_wait_one(h0, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                        ZX_TIME_INFINITE, NULL);
 
-    uint32_t types[2];
-    zx_handle_t handles[2];
+    uint32_t types[FDIO_MAX_HANDLES];
+    zx_handle_t handles[FDIO_MAX_HANDLES];
     uint32_t dcount, hcount;
-    if (zx_channel_read(h0, 0, types, handles, sizeof(types), 2, &dcount, &hcount) < 0) {
+    if (zx_channel_read(h0, 0, types, handles,
+                        sizeof(types), FDIO_MAX_HANDLES, &dcount, &hcount) < 0) {
         return -1;
     }
-    if ((dcount != sizeof(types)) || (hcount != 2)) {
+    if (dcount / sizeof(uint32_t) != hcount) {
         return -1;
     }
     zx_handle_close(h0);
@@ -70,17 +71,18 @@
 
     uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO;
 
-    fdio_spawn_action_t actions[] = {
+    fdio_spawn_action_t actions[1 + FDIO_MAX_HANDLES] = {
         {.action = FDIO_SPAWN_ACTION_SET_NAME, .name = {.data = pname}},
-        {.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
-         .h = {.id = types[0], .handle = handles[0]}},
-        {.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
-         .h = {.id = types[1], .handle = handles[1]}},
+    };
+    for (uint32_t i = 0; i < hcount; i++) {
+        actions[1 + i].action = FDIO_SPAWN_ACTION_ADD_HANDLE;
+        actions[1 + i].h.id = types[i];
+        actions[1 + i].h.handle = handles[i];
     };
 
     char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
     zx_status_t status = fdio_spawn_etc(ZX_HANDLE_INVALID, flags, argv[0], argv,
-                                  NULL, countof(actions), actions, NULL, err_msg);
+                                  NULL, 1 + hcount, actions, NULL, err_msg);
     if (status != ZX_OK) {
         fprintf(stderr, "error %d (%s) launching: %s\n", status,
                 zx_status_get_string(status), err_msg);