| // Copyright 2016 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. |
| |
| #include <stdlib.h> |
| |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include <fs/pseudo-dir.h> |
| #include <fs/service.h> |
| #include <fs/synchronous-vfs.h> |
| #include <fs/vfs.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/async/cpp/task.h> |
| #include <zircon/process.h> |
| #include <zircon/processargs.h> |
| |
| #include "garnet/bin/appmgr/dynamic_library_loader.h" |
| #include "garnet/bin/appmgr/realm.h" |
| #include "garnet/bin/appmgr/root_loader.h" |
| #include "lib/fxl/command_line.h" |
| #include "lib/fxl/files/file.h" |
| #include "lib/fxl/log_settings.h" |
| |
| namespace { |
| |
| constexpr char kRootLabel[] = "app"; |
| |
| void PublishRootDir(component::Realm* root, fs::SynchronousVfs* vfs) { |
| static zx_handle_t request = zx_get_startup_handle(PA_DIRECTORY_REQUEST); |
| if (request == ZX_HANDLE_INVALID) return; |
| fbl::RefPtr<fs::PseudoDir> dir(fbl::AdoptRef(new fs::PseudoDir())); |
| auto svc = fbl::AdoptRef(new fs::Service([root](zx::channel channel) { |
| return root->BindSvc(std::move(channel)); |
| })); |
| dir->AddEntry("hub", root->hub_dir()); |
| dir->AddEntry("svc", svc); |
| |
| vfs->ServeDirectory(dir, zx::channel(request)); |
| request = ZX_HANDLE_INVALID; |
| } |
| |
| } // namespace |
| |
| int main(int argc, char** argv) { |
| auto command_line = fxl::CommandLineFromArgcArgv(argc, argv); |
| |
| async::Loop loop(&kAsyncLoopConfigMakeDefault); |
| |
| fs::SynchronousVfs vfs(loop.async()); |
| component::RootLoader root_loader; |
| fbl::RefPtr<fs::PseudoDir> directory(fbl::AdoptRef(new fs::PseudoDir())); |
| directory->AddEntry( |
| component::Loader::Name_, |
| fbl::AdoptRef(new fs::Service([&root_loader](zx::channel channel) { |
| root_loader.AddBinding( |
| fidl::InterfaceRequest<component::Loader>(std::move(channel))); |
| return ZX_OK; |
| }))); |
| |
| zx::channel h1, h2; |
| if (zx::channel::create(0, &h1, &h2) < 0) return -1; |
| if (vfs.ServeDirectory(directory, std::move(h2)) != ZX_OK) return -1; |
| component::Realm root_realm(nullptr, std::move(h1), kRootLabel); |
| fs::SynchronousVfs publish_vfs(loop.async()); |
| PublishRootDir(&root_realm, &publish_vfs); |
| |
| component::ApplicationControllerPtr sysmgr; |
| auto run_sysmgr = [&root_realm, &sysmgr] { |
| component::LaunchInfo launch_info; |
| launch_info.url = "sysmgr"; |
| root_realm.CreateApplication(std::move(launch_info), sysmgr.NewRequest()); |
| }; |
| |
| async::PostTask(loop.async(), [&run_sysmgr, &sysmgr] { |
| run_sysmgr(); |
| sysmgr.set_error_handler(run_sysmgr); |
| }); |
| |
| loop.Run(); |
| return 0; |
| } |