[virtcon] Switch to fdio_spawn_etc

Most codepaths that create processes should use fdio_spawn rather than
launchpad directly.

Test: Manually verified that virtual consoles continue to work.

Change-Id: Ia2f2f62ef28565973da7c2e7d364800a7ecf815f
diff --git a/system/core/virtcon/main.cpp b/system/core/virtcon/main.cpp
index 8d8483b..a88f081 100644
--- a/system/core/virtcon/main.cpp
+++ b/system/core/virtcon/main.cpp
@@ -10,23 +10,21 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <launchpad/launchpad.h>
-
+#include <lib/fdio/io.h>
+#include <lib/fdio/spawn.h>
+#include <lib/fdio/util.h>
+#include <lib/fdio/watcher.h>
+#include <port/port.h>
 #include <zircon/device/pty.h>
 #include <zircon/device/vfs.h>
 #include <zircon/listnode.h>
 #include <zircon/process.h>
 #include <zircon/processargs.h>
+#include <zircon/status.h>
 #include <zircon/syscalls.h>
 #include <zircon/syscalls/log.h>
 #include <zircon/syscalls/object.h>
 
-#include <lib/fdio/io.h>
-#include <lib/fdio/util.h>
-#include <lib/fdio/watcher.h>
-
-#include <port/port.h>
-
 #include "vc.h"
 
 port_t port;
@@ -78,21 +76,30 @@
 }
 
 static zx_status_t launch_shell(vc_t* vc, int fd, const char* cmd) {
-    const char* args[] = { "/boot/bin/sh", "-c", cmd };
+    const char* argv[] = { "/boot/bin/sh", nullptr, nullptr, nullptr };
 
-    launchpad_t* lp;
-    launchpad_create(zx_job_default(), "vc:sh", &lp);
-    launchpad_load_from_file(lp, args[0]);
-    launchpad_set_args(lp, cmd ? 3 : 1, args);
-    launchpad_transfer_fd(lp, fd, FDIO_FLAG_USE_FOR_STDIO | 0);
-    launchpad_clone(lp, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_ENVIRON | LP_CLONE_DEFAULT_JOB);
-
-    const char* errmsg;
-    zx_status_t r;
-    if ((r = launchpad_go(lp, &vc->proc, &errmsg)) < 0) {
-        printf("vc: cannot spawn shell: %s: %d\n", errmsg, r);
+    if (cmd) {
+        argv[1] = "-c";
+        argv[2] = cmd;
     }
-    return r;
+
+    fdio_spawn_action_t actions[2] = {};
+    actions[0].action = FDIO_SPAWN_ACTION_SET_NAME;
+    actions[0].name.data = "vc:sh";
+    actions[1].action = FDIO_SPAWN_ACTION_TRANSFER_FD;
+    actions[1].fd = {.local_fd = fd, .target_fd = FDIO_FLAG_USE_FOR_STDIO};
+
+    uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO;
+
+    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
+    zx_status_t status = fdio_spawn_etc(ZX_HANDLE_INVALID, flags, argv[0], argv,
+                                        nullptr, countof(actions), actions,
+                                        &vc->proc, err_msg);
+    if (status != ZX_OK) {
+        printf("vc: cannot spawn shell: %s: %d (%s)\n", err_msg, status,
+               zx_status_get_string(status));
+    }
+    return status;
 }
 
 static void session_destroy(vc_t* vc) {
diff --git a/system/core/virtcon/rules.mk b/system/core/virtcon/rules.mk
index b8026ac..d1e7744 100644
--- a/system/core/virtcon/rules.mk
+++ b/system/core/virtcon/rules.mk
@@ -40,7 +40,7 @@
 
 MODULE_STATIC_LIBS := $(LOCAL_STATIC_LIBS)
 
-MODULE_LIBS := system/ulib/launchpad $(LOCAL_LIBS)
+MODULE_LIBS := $(LOCAL_LIBS)
 
 MODULE_FIDL_LIBS := $(LOCAL_FIDL_LIBS)