Revert "[virtcon] Make virtcon host a fidl service for sessions."
This reverts commit 35868fd43ba0d2aa649e7dda5c823acbe60ea8e4.
Reason for revert: There seems to be some inconsistent behavoir with the virtcons. Debug next week.
Original change's description:
> [virtcon] Make virtcon host a fidl service for sessions.
>
> the virtcon (virtual-console) binary used to provide new sessions
> through a convoluted path through device coordinator. This will make it
> expose a fidl service directly for clients to request a new session.
>
> This removes device coordinator from the operational loop and will make
> it easy for the virtual-console binary to stand on it's own once we have
> something else to start it.
>
> It is a little messy due to the virtcon binary using the "port" library
> heavily and fidl being built around the async_loop.
>
> Test:
> * Booted on vim2, core.arm64. Virtual consoles work as expected.
> * Booted astro, looks normal, "k ut all" and "runtests -a" pass.
>
> ZX-3403 # Get virtcon out of the way.
>
> Change-Id: I09e66a7c5bc91fb41b6bfb99510b5be1aa609d57
TBR=teisenbe@google.com,edcoyne@google.com
Change-Id: I53ebb9d2602e397317b9a70551ad63c62c96ac12
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
diff --git a/garnet/bin/appmgr/BUILD.gn b/garnet/bin/appmgr/BUILD.gn
index 6e1955c..286989b 100644
--- a/garnet/bin/appmgr/BUILD.gn
+++ b/garnet/bin/appmgr/BUILD.gn
@@ -60,7 +60,6 @@
"//zircon/public/fidl/fuchsia-inspect",
"//zircon/public/fidl/fuchsia-process",
"//zircon/public/fidl/fuchsia-scheduler",
- "//zircon/public/fidl/fuchsia-virtualconsole",
"//zircon/public/lib/async-loop-cpp",
"//zircon/public/lib/fit",
"//zircon/public/lib/fs",
diff --git a/garnet/bin/appmgr/component_controller_unittest.cc b/garnet/bin/appmgr/component_controller_unittest.cc
index 289d9d7..d7e9457 100644
--- a/garnet/bin/appmgr/component_controller_unittest.cc
+++ b/garnet/bin/appmgr/component_controller_unittest.cc
@@ -9,7 +9,6 @@
#include <fuchsia/device/manager/cpp/fidl.h>
#include <fuchsia/kernel/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
-#include <fuchsia/virtualconsole/cpp/fidl.h>
#include <lib/fdio/spawn.h>
#include <zircon/syscalls/object.h>
@@ -65,15 +64,14 @@
std::vector<std::string> GetDefaultNamespaceServiceEntries() {
return std::vector<std::string>{
".",
- Namespace::Launcher::Name_,
fuchsia::device::manager::Administrator::Name_,
fuchsia::device::manager::DebugDumper::Name_,
fuchsia::kernel::DebugBroker::Name_,
+ fuchsia::sys::Environment::Name_,
+ Namespace::Launcher::Name_,
fuchsia::process::Launcher::Name_,
fuchsia::process::Resolver::Name_,
fuchsia::scheduler::ProfileProvider::Name_,
- fuchsia::sys::Environment::Name_,
- fuchsia::virtualconsole::SessionManager::Name_,
};
}
diff --git a/garnet/bin/appmgr/integration_tests/hub_integration_test.cc b/garnet/bin/appmgr/integration_tests/hub_integration_test.cc
index 50b0586..f2d143e 100644
--- a/garnet/bin/appmgr/integration_tests/hub_integration_test.cc
+++ b/garnet/bin/appmgr/integration_tests/hub_integration_test.cc
@@ -95,8 +95,7 @@
"fuchsia.scheduler.ProfileProvider",
"fuchsia.sys.Environment",
"fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.virtualconsole.SessionManager"};
+ "fuchsia.sys.Loader"};
sysmgr::Config config;
ASSERT_TRUE(config.ParseFromDirectory("/system/data/sysmgr"));
// The following path is deprecated, and because config-data is component
diff --git a/garnet/bin/appmgr/namespace.cc b/garnet/bin/appmgr/namespace.cc
index 929a300e..8138b88 100644
--- a/garnet/bin/appmgr/namespace.cc
+++ b/garnet/bin/appmgr/namespace.cc
@@ -8,7 +8,6 @@
#include <fuchsia/kernel/cpp/fidl.h>
#include <fuchsia/process/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
-#include <fuchsia/virtualconsole/cpp/fidl.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
@@ -93,14 +92,6 @@
std::move(channel)));
return ZX_OK;
})));
- services_->AddService(
- fuchsia::virtualconsole::SessionManager::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- realm_->environment_services()->Connect(
- fidl::InterfaceRequest<fuchsia::virtualconsole::SessionManager>(
- std::move(channel)));
- return ZX_OK;
- })));
if (additional_services) {
auto& names = additional_services->names;
diff --git a/zircon/system/core/devmgr/devcoordinator/main.cpp b/zircon/system/core/devmgr/devcoordinator/main.cpp
index 45e8f5d..8de8b54 100644
--- a/zircon/system/core/devmgr/devcoordinator/main.cpp
+++ b/zircon/system/core/devmgr/devcoordinator/main.cpp
@@ -74,10 +74,6 @@
zx::channel svchost_outgoing;
zx::channel fs_root;
-
- // Used to bind the svchost to the virtual-console binary to provide fidl
- // services.
- zx::channel virtcon_fidl;
} g_handles;
// Wait for the requested file. Its parent directory must exist.
@@ -465,13 +461,6 @@
}
}
- zx::channel virtcon_client;
- status = zx::channel::create(0, &virtcon_client, &g_handles.virtcon_fidl);
- if (status != ZX_OK) {
- printf("Unable to create virtcon channel.\n");
- return status;
- }
-
// svchost needs to hold this to talk to zx_kerneldebug but doesn't need any rights.
// TODO(ZX-971): when zx_debug_send_command syscall is descoped, update this too.
zx::resource root_resource_copy;
@@ -512,11 +501,6 @@
// Add a handle to allow svchost to proxy services to fshost.
launchpad_add_handle(lp, fshost_client.release(), PA_HND(PA_USER0, 4));
- if (!coordinator->boot_args().GetBool("virtcon.disable", false)) {
- // Add handle to channel to allow svchost to proxy fidl services to
- // virtcon.
- launchpad_add_handle(lp, virtcon_client.release(), PA_HND(PA_USER0, 5));
- }
// Give svchost access to /dev/class/sysmem, to enable svchost to forward sysmem service
// requests to the sysmem driver. Create a namespace containing /dev/class/sysmem.
@@ -714,13 +698,18 @@
zx_handle_t handles[2];
uint32_t types[2];
- handles[handle_count] = g_handles.virtcon_fidl.release();
- types[handle_count] = PA_HND(PA_USER0, 0);
- ++handle_count;
+ zx::channel virtcon_client, virtcon_server;
+ zx_status_t status = zx::channel::create(0, &virtcon_client, &virtcon_server);
+ if (status == ZX_OK) {
+ coordinator->set_virtcon_channel(std::move(virtcon_client));
+ handles[handle_count] = virtcon_server.release();
+ types[handle_count] = PA_HND(PA_USER0, 0);
+ ++handle_count;
+ }
zx::debuglog debuglog;
- zx_status_t status = zx::debuglog::create(coordinator->root_resource(),
- ZX_LOG_FLAG_READABLE, &debuglog);
+ status = zx::debuglog::create(coordinator->root_resource(),
+ ZX_LOG_FLAG_READABLE, &debuglog);
if (status == ZX_OK) {
handles[handle_count] = debuglog.release();
types[handle_count] = PA_HND(PA_USER0, 1);
diff --git a/zircon/system/core/svchost/BUILD.gn b/zircon/system/core/svchost/BUILD.gn
index cb9f914..91df160 100644
--- a/zircon/system/core/svchost/BUILD.gn
+++ b/zircon/system/core/svchost/BUILD.gn
@@ -19,7 +19,6 @@
"$zx/system/fidl/fuchsia-process:c",
"$zx/system/fidl/fuchsia-scheduler:c",
"$zx/system/fidl/fuchsia-sysmem:c",
- "$zx/system/fidl/fuchsia-virtualconsole:c",
"$zx/system/ulib/async-loop:async-loop-cpp",
"$zx/system/ulib/fbl",
"$zx/system/ulib/fdio",
diff --git a/zircon/system/core/svchost/svchost.cpp b/zircon/system/core/svchost/svchost.cpp
index c0cc5a9..e4e4a26 100644
--- a/zircon/system/core/svchost/svchost.cpp
+++ b/zircon/system/core/svchost/svchost.cpp
@@ -9,7 +9,6 @@
#include <fs/remote-dir.h>
#include <fuchsia/device/manager/c/fidl.h>
#include <fuchsia/fshost/c/fidl.h>
-#include <fuchsia/virtualconsole/c/fidl.h>
#include <fuchsia/net/c/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/fd.h>
@@ -201,7 +200,7 @@
}
}
-void publish_remote_service(const fbl::RefPtr<fs::PseudoDir>& dir,
+void publish_proxy_service(const fbl::RefPtr<fs::PseudoDir>& dir,
const char* name, zx::unowned_channel forwarding_channel) {
fbl::String path = fbl::StringPrintf("public/%s", name);
dir->AddEntry(name, fbl::MakeRefCounted<fs::Service>(
@@ -210,18 +209,6 @@
}));
}
-//TODO(edcoyne): remove this and make virtcon talk virtual filesystems too.
-void publish_proxy_service(const fbl::RefPtr<fs::PseudoDir>& dir,
- const char* name, zx::unowned_channel forwarding_channel) {
- dir->AddEntry(name, fbl::MakeRefCounted<fs::Service>(
- [name, forwarding_channel = std::move(forwarding_channel)](zx::channel request) {
- const auto request_handle = request.release();
- return forwarding_channel->write(0, name, static_cast<uint32_t>(strlen(name)),
- &request_handle, 1);
- }));
-}
-
-
int main(int argc, char** argv) {
bool require_system = false;
if (argc > 1) {
@@ -236,7 +223,6 @@
root_resource = zx_take_startup_handle(PA_HND(PA_USER0, 2));
zx::channel devmgr_proxy_channel = zx::channel(zx_take_startup_handle(PA_HND(PA_USER0, 3)));
zx::channel fshost_svc = zx::channel(zx_take_startup_handle(PA_HND(PA_USER0, 4)));
- zx::channel virtcon_proxy_channel = zx::channel(zx_take_startup_handle(PA_HND(PA_USER0, 5)));
zx_status_t status = outgoing.ServeFromStartupInfo();
if (status != ZX_OK) {
@@ -293,19 +279,13 @@
publish_services(outgoing.public_dir(), deprecated_services, zx::unowned_channel(appmgr_svc));
publish_services(outgoing.public_dir(), fshost_services, zx::unowned_channel(fshost_svc));
- publish_remote_service(outgoing.public_dir(),
+ publish_proxy_service(outgoing.public_dir(),
fuchsia_device_manager_DebugDumper_Name,
zx::unowned_channel(devmgr_proxy_channel));
- publish_remote_service(outgoing.public_dir(),
+ publish_proxy_service(outgoing.public_dir(),
fuchsia_device_manager_Administrator_Name,
zx::unowned_channel(devmgr_proxy_channel));
- if (virtcon_proxy_channel.is_valid()) {
- publish_proxy_service(outgoing.public_dir(),
- fuchsia_virtualconsole_SessionManager_Name,
- zx::unowned_channel(virtcon_proxy_channel));
- }
-
start_crashsvc(zx::job(root_job),
require_system? appmgr_svc : ZX_HANDLE_INVALID);
diff --git a/zircon/system/core/virtcon/BUILD.gn b/zircon/system/core/virtcon/BUILD.gn
index b221a98..48eab4c 100644
--- a/zircon/system/core/virtcon/BUILD.gn
+++ b/zircon/system/core/virtcon/BUILD.gn
@@ -27,11 +27,9 @@
"$zx/system/fidl/fuchsia-hardware-input:c",
"$zx/system/fidl/fuchsia-hardware-pty:c",
"$zx/system/fidl/fuchsia-io:c",
- "$zx/system/fidl/fuchsia-virtualconsole:c",
"$zx/system/ulib/fbl",
"$zx/system/ulib/fdio",
"$zx/system/ulib/fidl",
- "$zx/system/ulib/fs",
"$zx/system/ulib/fzl",
"$zx/system/ulib/gfx",
"$zx/system/ulib/gfx-font-data",
diff --git a/zircon/system/core/virtcon/main.cpp b/zircon/system/core/virtcon/main.cpp
index c42c4be..8f5310b 100644
--- a/zircon/system/core/virtcon/main.cpp
+++ b/zircon/system/core/virtcon/main.cpp
@@ -9,20 +9,16 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <memory>
#include <fbl/algorithm.h>
-#include <fbl/string_piece.h>
#include <fbl/unique_fd.h>
-#include <fs/handler.h>
#include <fuchsia/hardware/pty/c/fidl.h>
#include <fuchsia/io/c/fidl.h>
-#include <fuchsia/virtualconsole/c/fidl.h>
-#include <lib/fdio/directory.h>
-#include <lib/fdio/fd.h>
-#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
+#include <lib/fdio/fd.h>
+#include <lib/fdio/fdio.h>
+#include <lib/fdio/directory.h>
#include <lib/fdio/watcher.h>
#include <lib/fzl/fdio.h>
#include <lib/zx/channel.h>
@@ -160,7 +156,7 @@
return ZX_ERR_STOP;
}
-static zx_status_t remote_session_create(vc_t** out, zx::channel session, bool make_active, bool special) {
+static zx_status_t session_create(vc_t** out, int* out_fd, bool make_active, bool special) {
// The ptmx device can start later than these threads
int retry = 30;
int raw_fd;
@@ -177,9 +173,14 @@
return ZX_ERR_INTERNAL;
}
- zx_status_t status;
+ zx::channel device_channel, client_channel;
+ zx_status_t status = zx::channel::create(0, &device_channel, &client_channel);
+ if (status != ZX_OK) {
+ return status;
+ }
+
zx_status_t fidl_status = fuchsia_hardware_pty_DeviceOpenClient(
- fdio_unsafe_borrow_channel(io), 0, session.release(), &status);
+ fdio_unsafe_borrow_channel(io), 0, device_channel.release(), &status);
fdio_unsafe_release(io);
if (fidl_status != ZX_OK) {
return fidl_status;
@@ -188,6 +189,13 @@
return status;
}
+ int raw_client_fd;
+ status = fdio_fd_create(client_channel.release(), &raw_client_fd);
+ if (status != ZX_OK) {
+ return status;
+ }
+ fbl::unique_fd client_fd(raw_client_fd);
+
vc_t* vc;
if (vc_create(&vc, special)) {
return ZX_ERR_INTERNAL;
@@ -217,35 +225,13 @@
vc->fh.func = session_io_cb;
*out = vc;
- return ZX_OK;
-}
-
-static zx_status_t session_create(vc_t** out, int* out_fd, bool make_active, bool special) {
- zx::channel device_channel, client_channel;
- zx_status_t status = zx::channel::create(0, &device_channel, &client_channel);
- if (status != ZX_OK) {
- return status;
- }
-
- status = remote_session_create(out, std::move(device_channel), make_active, special);
- if (status != ZX_OK) {
- return status;
- }
-
- int raw_client_fd;
- status = fdio_fd_create(client_channel.release(), &raw_client_fd);
- if (status != ZX_OK) {
- return status;
- }
- fbl::unique_fd client_fd(raw_client_fd);
-
*out_fd = client_fd.release();
return ZX_OK;
}
static void start_shell(bool make_active, const char* cmd) {
- vc_t* vc = nullptr;
- int fd = 0;
+ vc_t* vc;
+ int fd;
if (session_create(&vc, &fd, make_active, cmd != NULL) < 0) {
return;
@@ -260,81 +246,36 @@
}
}
-static zx_status_t new_vc_cb(void*, zx_handle_t session) {
- zx::channel session_channel(session);
+static zx_status_t new_vc_cb(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
+ zx::channel h;
+ uint32_t dcount, hcount;
+ if (zx_channel_read(ph->handle, 0, NULL, h.reset_and_get_address(), 0, 1, &dcount, &hcount) < 0) {
+ return ZX_OK;
+ }
+ if (hcount != 1) {
+ return ZX_OK;
+ }
- vc_t* vc = nullptr;
- if (remote_session_create(&vc, std::move(session_channel), true, false) < 0) {
+ vc_t* vc;
+ int fd;
+ if (session_create(&vc, &fd, true, false) < 0) {
+ return ZX_OK;
+ }
+
+ zx_handle_t handle = ZX_HANDLE_INVALID;
+ uint32_t type = PA_HND(PA_FD, FDIO_FLAG_USE_FOR_STDIO);
+ zx_status_t status = fdio_fd_transfer(fd, &handle);
+ if (status != ZX_OK) {
+ session_destroy(vc);
+ return ZX_OK;
+ }
+ status = h.write(0, &type, static_cast<uint32_t>(sizeof(type)), &handle, 1);
+ if (status != ZX_OK) {
+ session_destroy(vc);
return ZX_OK;
}
port_wait(&port, &vc->fh.ph);
-
- return ZX_OK;
-}
-
-static zx_status_t fidl_message_cb(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
- if (signals & ZX_CHANNEL_PEER_CLOSED) {
- zx_handle_close(ph->handle);
- delete ph;
- return ZX_ERR_STOP;
- }
-
- auto status = fs::ReadMessage(ph->handle, [](fidl_msg_t* message, fs::FidlConnection* txn) {
- static constexpr fuchsia_virtualconsole_SessionManager_ops_t kOps {
- .CreateSession = new_vc_cb,
- };
-
- return fuchsia_virtualconsole_SessionManager_dispatch(nullptr,
- reinterpret_cast<fidl_txn_t*>(&txn),
- message,
- &kOps);
- });
-
- if (status != ZX_OK) {
- printf("Failed to dispatch fidl message from client: %s\n", zx_status_get_string(status));
- zx_handle_close(ph->handle);
- delete ph;
- return ZX_ERR_STOP;
- }
-
- return ZX_OK;
-}
-
-static zx_status_t fidl_connection_cb(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
- constexpr size_t kBufferSize = 256;
- char buffer[kBufferSize];
-
- uint32_t bytes_read, handles_read;
- zx_handle_t client_raw;
- auto status = zx_channel_read(ph->handle, 0,
- buffer, &client_raw,
- kBufferSize, 1,
- &bytes_read, &handles_read);
- if (status != ZX_OK) {
- printf("Failed to read from channel: %s\n", zx_status_get_string(status));
- return ZX_OK;
- }
-
- if (handles_read < 1) {
- printf("Fidl connection with no channel.\n");
- return ZX_OK;
- }
- zx::channel client(client_raw);
-
- if (fbl::StringPiece(fuchsia_virtualconsole_SessionManager_Name) ==
- fbl::StringPiece(buffer, bytes_read)) {
- auto handler = std::unique_ptr<port_handler_t>(new port_handler_t {
- .handle = client.release(),
- .waitfor = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
- .func = fidl_message_cb,
- });
-
- port_wait(&port, handler.release());
- } else {
- printf("Unsupported fidl interface: %.*s\n", bytes_read, buffer);
- }
-
return ZX_OK;
}
@@ -501,7 +442,7 @@
log_ph.waitfor = ZX_LOG_READABLE;
if ((new_vc_ph.handle = zx_take_startup_handle(PA_HND(PA_USER0, 0))) != ZX_HANDLE_INVALID) {
- new_vc_ph.func = fidl_connection_cb;
+ new_vc_ph.func = new_vc_cb;
new_vc_ph.waitfor = ZX_CHANNEL_READABLE;
port_wait(&port, &new_vc_ph);
}
diff --git a/zircon/system/fidl/fuchsia-virtualconsole/BUILD.gn b/zircon/system/fidl/fuchsia-virtualconsole/BUILD.gn
deleted file mode 100644
index 7cfa778..0000000
--- a/zircon/system/fidl/fuchsia-virtualconsole/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("$zx/public/gn/fidl.gni")
-
-fidl_library("fuchsia-virtualconsole") {
- sources = [
- "session-manager.fidl",
- ]
- public_deps = [
- "$zx/system/fidl/fuchsia-hardware-pty",
- ]
-}
diff --git a/zircon/system/fidl/fuchsia-virtualconsole/session-manager.fidl b/zircon/system/fidl/fuchsia-virtualconsole/session-manager.fidl
deleted file mode 100644
index fb33053..0000000
--- a/zircon/system/fidl/fuchsia-virtualconsole/session-manager.fidl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.virtualconsole;
-
-using zx;
-using fuchsia.hardware.pty;
-
-/// Manages virtual console sessions.
-[Discoverable, Layout = "Simple"]
-protocol SessionManager {
- /// Create a new virtual console session.
- CreateSession(request<fuchsia.hardware.pty.Device> session);
-};
diff --git a/zircon/system/uapp/run-vc/BUILD.gn b/zircon/system/uapp/run-vc/BUILD.gn
index 00f553ae..7de523b 100644
--- a/zircon/system/uapp/run-vc/BUILD.gn
+++ b/zircon/system/uapp/run-vc/BUILD.gn
@@ -7,7 +7,7 @@
"main.c",
]
deps = [
- "$zx/system/fidl/fuchsia-virtualconsole:c",
+ "$zx/system/fidl/fuchsia-device-manager:c",
"$zx/system/ulib/fdio",
"$zx/system/ulib/zircon",
]
diff --git a/zircon/system/uapp/run-vc/main.c b/zircon/system/uapp/run-vc/main.c
index 213a7e0..782e568 100644
--- a/zircon/system/uapp/run-vc/main.c
+++ b/zircon/system/uapp/run-vc/main.c
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include <fcntl.h>
-#include <fuchsia/virtualconsole/c/fidl.h>
+#include <fuchsia/device/manager/c/fidl.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/fd.h>
@@ -32,51 +32,67 @@
return ZX_OK;
};
-static zx_status_t connect_to_service(const char* service, zx_handle_t* channel) {
- zx_handle_t channel_local, channel_remote;
- zx_status_t status = zx_channel_create(0, &channel_local, &channel_remote);
- if (status != ZX_OK) {
- printf("failed to create channel: %s\n", zx_status_get_string(status));
- return false;
+static zx_status_t open_dmctl(int* fd) {
+ int dirfd = open("/dev/misc", O_RDONLY);
+ if (dirfd < 0) {
+ return ZX_ERR_IO;
}
-
- status = fdio_service_connect(service, channel_remote);
- if (status != ZX_OK) {
- zx_handle_close(channel_local);
- printf("failed to connect to service: %s\n", zx_status_get_string(status));
- return false;
+ zx_status_t status = fdio_watch_directory(dirfd, dmctl_watch_func, ZX_TIME_INFINITE, NULL);
+ if (status != ZX_ERR_STOP) {
+ if (status == ZX_OK) {
+ status = ZX_ERR_BAD_STATE;
+ }
+ printf("failed to watch /dev/misc: %s\n", zx_status_get_string(status));
+ close(dirfd);
+ return status;
}
-
- *channel = channel_local;
- return true;
-
+ *fd = openat(dirfd, "dmctl", O_RDWR);
+ close(dirfd);
+ if (*fd < 0) {
+ return ZX_ERR_IO;
+ }
+ return ZX_OK;
}
int main(int argc, const char** argv) {
- zx_handle_t session_manager = ZX_HANDLE_INVALID;
- if (!connect_to_service("/svc/fuchsia.virtualconsole.SessionManager", &session_manager)) {
- return -1;
- }
-
-
- zx_handle_t session, session_remote;
- if (zx_channel_create(0, &session, &session_remote) != ZX_OK) {
- return -1;
- }
-
- zx_status_t status = fuchsia_virtualconsole_SessionManagerCreateSession(session_manager,
- session_remote);
+ int fd;
+ zx_status_t status = open_dmctl(&fd);
if (status != ZX_OK) {
- fprintf(stderr, "run-vc: failed to create session: %s\n", zx_status_get_string(status));
+ fprintf(stderr, "failed to open dmctl: %s\n", zx_status_get_string(status));
+ return -1;
+ }
+ zx_handle_t dmctl;
+ status = fdio_get_service_handle(fd, &dmctl);
+ if (status != ZX_OK) {
+ fprintf(stderr, "error %s converting fd to handle\n", zx_status_get_string(status));
return -1;
}
-
- if (session == ZX_HANDLE_INVALID) {
- fprintf(stderr, "Received invalid handle from session manager!\n");
+ zx_handle_t h0, h1;
+ if (zx_channel_create(0, &h0, &h1) < 0) {
return -1;
}
+ if (fuchsia_device_manager_ExternalControllerOpenVirtcon(dmctl, h1) < 0) {
+ return -1;
+ }
+ h1 = ZX_HANDLE_INVALID;
+ zx_handle_close(dmctl);
+
+ zx_object_wait_one(h0, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
+ ZX_TIME_INFINITE, NULL);
+
+ uint32_t type = 0;
+ zx_handle_t handle = ZX_HANDLE_INVALID;
+ uint32_t dcount = 0, hcount = 0;
+ if (zx_channel_read(h0, 0, &type, &handle, sizeof(type), 1, &dcount, &hcount) != ZX_OK) {
+ return -1;
+ }
+ if (dcount / sizeof(uint32_t) != hcount) {
+ return -1;
+ }
+ zx_handle_close(h0);
+
// start shell if no arguments
if (argc == 1) {
argv[0] = "/boot/bin/sh";
@@ -92,16 +108,15 @@
}
uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO;
- uint32_t type = PA_HND(PA_FD, FDIO_FLAG_USE_FOR_STDIO);
fdio_spawn_action_t actions[2] = {
{.action = FDIO_SPAWN_ACTION_SET_NAME, .name = {.data = pname}},
- {.action = FDIO_SPAWN_ACTION_ADD_HANDLE, .h = {.id = type, .handle = session}},
+ {.action = FDIO_SPAWN_ACTION_ADD_HANDLE, .h = {.id = type, .handle = handle}},
};
char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
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);