From 745eb8923736315e7cd3b7c567dd6a2bedb2786b Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Tue, 3 Jan 2017 14:33:55 +0100 Subject: [PATCH] lib/component: pass extended Libc::Env Libc::Env is the Genode::Env interface extended to cover access to the XML content of the 'config' ROM and a VFS instance. This deduplicates the burden of components to attain and manage these resources. Fix #2217 Ref #1987 --- repos/dde_linux/src/drivers/wifi/main.cc | 2 +- repos/gems/src/app/backdrop/main.cc | 2 +- repos/gems/src/app/menu_view/main.cc | 2 +- repos/gems/src/app/themed_decorator/main.cc | 2 +- repos/gems/src/server/http_blk/main.cc | 2 +- repos/gems/src/server/terminal_mux/main.cc | 2 +- repos/libports/include/libc/component.h | 51 +++++--- repos/libports/lib/mk/libc.mk | 2 +- repos/libports/lib/symbols/libc | 2 +- repos/libports/run/ldso.run | 5 +- repos/libports/run/libc.run | 5 +- repos/libports/src/app/acpica/os.cc | 2 +- repos/libports/src/app/qt5/qt_avplay/main.cpp | 2 +- .../src/app/qt5/qt_launchpad/main.cpp | 2 +- repos/libports/src/lib/libc/task.cc | 118 ++++++++++++++++-- repos/libports/src/lib/libc/vfs_plugin.cc | 40 ------ repos/libports/src/lib/libc/vfs_plugin.h | 101 +++++++-------- repos/libports/src/lib/posix/construct.cc | 2 +- .../src/server/fuse_fs/fuse_fs_main.cc | 2 +- repos/libports/src/test/ldso/main.cc | 2 +- repos/libports/src/test/libports/main.cc | 2 +- repos/os/src/test/blk/bench/main.cc | 2 +- repos/ports/src/app/gdb_monitor/main.cc | 2 +- repos/ports/src/app/openvpn/main.cc | 2 +- repos/ports/src/noux/main.cc | 2 +- repos/ports/src/virtualbox/frontend/main.cc | 2 +- repos/ports/src/virtualbox5/frontend/main.cc | 2 +- 27 files changed, 216 insertions(+), 146 deletions(-) diff --git a/repos/dde_linux/src/drivers/wifi/main.cc b/repos/dde_linux/src/drivers/wifi/main.cc index ff9351b119..678d7426dd 100644 --- a/repos/dde_linux/src/drivers/wifi/main.cc +++ b/repos/dde_linux/src/drivers/wifi/main.cc @@ -254,4 +254,4 @@ struct Main }; -void Libc::Component::construct(Genode::Env &env) { static Main server(env); } +void Libc::Component::construct(Libc::Env &env) { static Main server(env); } diff --git a/repos/gems/src/app/backdrop/main.cc b/repos/gems/src/app/backdrop/main.cc index ba0d9d6049..84fe8b4556 100644 --- a/repos/gems/src/app/backdrop/main.cc +++ b/repos/gems/src/app/backdrop/main.cc @@ -366,6 +366,6 @@ void Backdrop::Main::handle_sync() extern "C" void _sigprocmask() { } -void Libc::Component::construct(Genode::Env &env) { +void Libc::Component::construct(Libc::Env &env) { static Backdrop::Main application(env); } diff --git a/repos/gems/src/app/menu_view/main.cc b/repos/gems/src/app/menu_view/main.cc index 5252161521..18716c3875 100644 --- a/repos/gems/src/app/menu_view/main.cc +++ b/repos/gems/src/app/menu_view/main.cc @@ -292,5 +292,5 @@ void Menu_view::Main::_handle_frame_timer() extern "C" void _sigprocmask() { } -void Libc::Component::construct(Genode::Env &env) { static Menu_view::Main main(env); } +void Libc::Component::construct(Libc::Env &env) { static Menu_view::Main main(env); } diff --git a/repos/gems/src/app/themed_decorator/main.cc b/repos/gems/src/app/themed_decorator/main.cc index 1687d3d72f..3c207d46e1 100644 --- a/repos/gems/src/app/themed_decorator/main.cc +++ b/repos/gems/src/app/themed_decorator/main.cc @@ -317,4 +317,4 @@ void Decorator::Main::_handle_pointer_update() } -void Libc::Component::construct(Genode::Env &env) { static Decorator::Main main(env); } +void Libc::Component::construct(Libc::Env &env) { static Decorator::Main main(env); } diff --git a/repos/gems/src/server/http_blk/main.cc b/repos/gems/src/server/http_blk/main.cc index c31b40e5d5..2aa0e5899b 100644 --- a/repos/gems/src/server/http_blk/main.cc +++ b/repos/gems/src/server/http_blk/main.cc @@ -107,4 +107,4 @@ struct Main }; -void Libc::Component::construct(Genode::Env &env) { static Main m(env); } +void Libc::Component::construct(Libc::Env &env) { static Main m(env); } diff --git a/repos/gems/src/server/terminal_mux/main.cc b/repos/gems/src/server/terminal_mux/main.cc index c71f2bb6f2..4c0787a220 100644 --- a/repos/gems/src/server/terminal_mux/main.cc +++ b/repos/gems/src/server/terminal_mux/main.cc @@ -721,4 +721,4 @@ struct Main }; -void Libc::Component::construct(Genode::Env &env) { static Main inst(env); } +void Libc::Component::construct(Libc::Env &env) { static Main inst(env); } diff --git a/repos/libports/include/libc/component.h b/repos/libports/include/libc/component.h index c7efb79cad..3270c729c5 100644 --- a/repos/libports/include/libc/component.h +++ b/repos/libports/include/libc/component.h @@ -21,28 +21,51 @@ #ifndef _INCLUDE__LIBC__COMPONENT_H_ #define _INCLUDE__LIBC__COMPONENT_H_ +#include #include #include -namespace Genode { struct Env; } - /** * Interface to be provided by the component implementation */ -namespace Libc { namespace Component { +namespace Libc { - /** - * Return stack size of the component's initial entrypoint - */ - Genode::size_t stack_size(); + class Env : public Genode::Env + { + private: - /** - * Construct component - * - * \param env interface to the component's execution environment - */ - void construct(Genode::Env &env); -} } + virtual Genode::Xml_node _config_xml() const = 0; + + public: + + /** + * Component configuration + */ + template + void config(FUNC const &func) const { + func(_config_xml()); } + + /** + * Virtual File System configured for this component + */ + virtual Vfs::File_system &vfs() = 0; + }; + + namespace Component { + + /** + * Return stack size of the component's initial entrypoint + */ + Genode::size_t stack_size(); + + /** + * Construct component + * + * \param env extended interface to the component's execution environment + */ + void construct(Libc::Env &env); + } +} #endif /* _INCLUDE__LIBC__COMPONENT_H_ */ diff --git a/repos/libports/lib/mk/libc.mk b/repos/libports/lib/mk/libc.mk index 64ac062977..b4d6dcdd81 100644 --- a/repos/libports/lib/mk/libc.mk +++ b/repos/libports/lib/mk/libc.mk @@ -4,7 +4,7 @@ LIBS = libc-string libc-locale libc-stdlib libc-stdio libc-gen libc-gdtoa \ libc-inet libc-stdtime libc-regex libc-compat libc-setjmp libc-mem -LIBS += base config vfs +LIBS += base vfs # # Back end diff --git a/repos/libports/lib/symbols/libc b/repos/libports/lib/symbols/libc index 10bc759b31..6f023fcf99 100644 --- a/repos/libports/lib/symbols/libc +++ b/repos/libports/lib/symbols/libc @@ -933,7 +933,7 @@ _write T _writev T -_ZN4Libc9Component9constructERN6Genode3EnvE U +_ZN4Libc9Component9constructERNS_3EnvE U # # Libc plugin interface diff --git a/repos/libports/run/ldso.run b/repos/libports/run/ldso.run index eaca0e696e..8ad66cb939 100644 --- a/repos/libports/run/ldso.run +++ b/repos/libports/run/ldso.run @@ -15,9 +15,8 @@ set config { - - - + + diff --git a/repos/libports/run/libc.run b/repos/libports/run/libc.run index 12ed9c719c..90ccb4a4b9 100644 --- a/repos/libports/run/libc.run +++ b/repos/libports/run/libc.run @@ -22,9 +22,8 @@ install_config { - - - + + diff --git a/repos/libports/src/app/acpica/os.cc b/repos/libports/src/app/acpica/os.cc index 01ac06c998..2c494b7e5b 100644 --- a/repos/libports/src/app/acpica/os.cc +++ b/repos/libports/src/app/acpica/os.cc @@ -307,4 +307,4 @@ ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler, /* used by normal (no-printf-debug) target */ void Component::construct(Genode::Env &env) { static Acpica::Main main(env); } /* used by debug target (using printf of libc) */ -void Libc::Component::construct(Genode::Env &env) { static Acpica::Main main(env); } +void Libc::Component::construct(Libc::Env &env) { static Acpica::Main main(env); } diff --git a/repos/libports/src/app/qt5/qt_avplay/main.cpp b/repos/libports/src/app/qt5/qt_avplay/main.cpp index 4e00496188..eef3552de9 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main.cpp +++ b/repos/libports/src/app/qt5/qt_avplay/main.cpp @@ -37,7 +37,7 @@ static inline void load_stylesheet() extern int genode_argc; extern char **genode_argv; -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { QApplication app(genode_argc, genode_argv); diff --git a/repos/libports/src/app/qt5/qt_launchpad/main.cpp b/repos/libports/src/app/qt5/qt_launchpad/main.cpp index ea81e150c7..9732a28b7c 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/main.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/main.cpp @@ -57,7 +57,7 @@ struct Qt_launchpad_namespace::Local_env : Genode::Env }; -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { static Qt_launchpad_namespace::Local_env local_env(env); diff --git a/repos/libports/src/lib/libc/task.cc b/repos/libports/src/lib/libc/task.cc index 67fd182c06..6e1923282f 100644 --- a/repos/libports/src/lib/libc/task.cc +++ b/repos/libports/src/lib/libc/task.cc @@ -13,11 +13,12 @@ /* Genode includes */ #include -#include #include #include #include #include +#include +#include /* libc includes */ #include @@ -44,7 +45,10 @@ } while (0) -namespace Libc { class Task; } +namespace Libc { + class Env_implementation; + class Task; +} struct Task_resume @@ -54,6 +58,102 @@ struct Task_resume }; +class Libc::Env_implementation : public Libc::Env +{ + private: + + Genode::Env &_env; + + Genode::Attached_rom_dataspace _config { _env, "config" }; + + Genode::Xml_node _vfs_config() + { + try { return _config.xml().sub_node("vfs"); } + catch (Genode::Xml_node::Nonexistent_sub_node) { } + try { + Genode::Xml_node node = + _config.xml().sub_node("libc").sub_node("vfs"); + Genode::warning("' ' is deprecated, " + "please move to ' '"); + return node; + } + catch (Genode::Xml_node::Nonexistent_sub_node) { } + + return Genode::Xml_node(""); + } + + Vfs::Dir_file_system _vfs; + + Genode::Xml_node _config_xml() const override { + return _config.xml(); }; + + public: + + Env_implementation(Genode::Env &env, Genode::Allocator &alloc) + : + _env(env), + _vfs(_env, alloc, _vfs_config(), + Vfs::global_file_system_factory()) + { } + + + /************************* + ** Libc::Env interface ** + *************************/ + + Vfs::File_system &vfs() override { + return _vfs; } + + + /*************************** + ** Genode::Env interface ** + ***************************/ + + Parent &parent() override { + return _env.parent(); } + + Ram_session &ram() override { + return _env.ram(); } + + Cpu_session &cpu() override { + return _env.cpu(); } + + Region_map &rm() override { + return _env.rm(); } + + Pd_session &pd() override { + return _env.pd(); } + + Entrypoint &ep() override { + return _env.ep(); } + + Ram_session_capability ram_session_cap() override { + return _env.ram_session_cap(); } + Cpu_session_capability cpu_session_cap() override { + return _env.cpu_session_cap(); } + + Pd_session_capability pd_session_cap() override { + return _env.pd_session_cap(); } + + Id_space &id_space() override { + return _env.id_space(); } + + Session_capability session(Parent::Service_name const &name, + Parent::Client::Id id, + Parent::Session_args const &args, + Affinity const &aff) override { + return _env.session(name, id, args, aff); } + + + void upgrade(Parent::Client::Id id, + Parent::Upgrade_args const &args) override { + return _env.upgrade(id, args); } + + void close(Parent::Client::Id id) override { + return _env.close(id); } +}; + + /** * Libc task * @@ -68,12 +168,10 @@ class Libc::Task : public Genode::Rpc_object { private: - Genode::Env &_env; - - /* XXX: this heap is only used by the Vfs_plugin */ - Genode::Heap _heap { &_env.ram(), &_env.rm() }; - - Vfs_plugin _vfs { _env, _heap }; + Genode::Env &_env; + Genode::Heap _heap { _env.ram(), _env.rm() }; + Env_implementation _libc_env { _env, _heap }; + Vfs_plugin _vfs { _libc_env, _heap }; /** * Application context and execution state @@ -158,9 +256,11 @@ class Libc::Task : public Genode::Rpc_object ** Libc task implementation ** ******************************/ +extern "C" void wait_for_continue(void); + void Libc::Task::_app_entry(Task *task) { - Libc::Component::construct(task->_env); + Libc::Component::construct(task->_libc_env); /* returned from task - switch stack to libc and return to dispatch loop */ _longjmp(task->_libc_task, 1); diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 42224c1a1d..524767b65a 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -83,14 +83,6 @@ namespace Libc { return Genode::config()->xml_node().sub_node("libc"); } - - Genode::Xml_node vfs_config() __attribute__((weak)); - Genode::Xml_node vfs_config() - { - return Libc::config().sub_node("vfs"); - } - - class Config_attr { private: @@ -110,38 +102,6 @@ namespace Libc { char const *string() const { return _buf; } }; - - char const *initial_cwd() __attribute__((weak)); - char const *initial_cwd() - { - static Config_attr initial_cwd("cwd", "/"); - return initial_cwd.string(); - } - - - char const *config_stdin() __attribute__((weak)); - char const *config_stdin() - { - static Config_attr stdin("stdin", ""); - return stdin.string(); - } - - - char const *config_stdout() __attribute__((weak)); - char const *config_stdout() - { - static Config_attr stdout("stdout", ""); - return stdout.string(); - } - - - char const *config_stderr() __attribute__((weak)); - char const *config_stderr() - { - static Config_attr stderr("stderr", ""); - return stderr.string(); - } - char const *config_rtc() __attribute__((weak)); char const *config_rtc() { diff --git a/repos/libports/src/lib/libc/vfs_plugin.h b/repos/libports/src/lib/libc/vfs_plugin.h index 67aed05c17..6ece55d962 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.h +++ b/repos/libports/src/lib/libc/vfs_plugin.h @@ -15,10 +15,7 @@ #define _LIBC_VFS__PLUGIN_H_ /* Genode includes */ -#include -#include -#include -#include +#include /* libc includes */ #include @@ -28,19 +25,6 @@ #include #include -namespace Libc { - - Genode::Xml_node config(); - Genode::Xml_node vfs_config(); - - char const *initial_cwd(); - char const *config_stdin(); - char const *config_stdout(); - char const *config_stderr(); - -} - - namespace Libc { class Vfs_plugin; } @@ -50,41 +34,39 @@ class Libc::Vfs_plugin : public Libc::Plugin Genode::Allocator &_alloc; - Vfs::Dir_file_system _root_dir; + Vfs::File_system &_root_dir; - Genode::Xml_node _vfs_config() + void _open_stdio(Genode::Xml_node const &node, char const *attr, + int libc_fd, unsigned flags) { try { - return vfs_config(); - } catch (...) { - PINF("no VFS configured"); - return Genode::Xml_node(""); - } - } + Genode::String path; + struct stat out_stat; - void _open_stdio(int libc_fd, char const *path, unsigned flags) - { - struct stat out_stat; - if (::strlen(path) == 0 || stat(path, &out_stat) != 0) - return; + node.attribute(attr).value(&path); - Libc::File_descriptor *fd = open(path, flags, libc_fd); - if (fd->libc_fd != libc_fd) { - PERR("could not allocate fd %d for %s, got fd %d", - libc_fd, path, fd->libc_fd); - close(fd); - return; - } + if (stat(path.string(), &out_stat) != 0) + return; - /* - * We need to manually register the path. Normally this is done - * by '_open'. But we call the local 'open' function directly - * because we want to explicitly specify the libc fd ID. - * - * We have to allocate the path from the libc (done via 'strdup') - * such that the path can be freed when an stdio fd is closed. - */ - fd->fd_path = strdup(path); + Libc::File_descriptor *fd = open(path.string(), flags, libc_fd); + if (fd->libc_fd != libc_fd) { + Genode::error("could not allocate fd ",libc_fd," for ",path,", " + "got fd ",fd->libc_fd); + close(fd); + return; + } + + /* + * We need to manually register the path. Normally this is done + * by '_open'. But we call the local 'open' function directly + * because we want to explicitly specify the libc fd ID. + * + * We have to allocate the path from the libc (done via 'strdup') + * such that the path can be freed when an stdio fd is closed. + */ + fd->fd_path = strdup(path.string()); + + } catch (Xml_node::Nonexistent_attribute) { } } public: @@ -92,19 +74,26 @@ class Libc::Vfs_plugin : public Libc::Plugin /** * Constructor */ - Vfs_plugin(Genode::Env &env, Genode::Allocator &alloc) + Vfs_plugin(Libc::Env &env, Genode::Allocator &alloc) : - _alloc(alloc), - _root_dir(env, _alloc, _vfs_config(), - Vfs::global_file_system_factory()) + _alloc(alloc), _root_dir(env.vfs()) { - if (_root_dir.num_dirent("/")) { - chdir(initial_cwd()); + using Genode::Xml_node; - _open_stdio(0, config_stdin(), O_RDONLY); - _open_stdio(1, config_stdout(), O_WRONLY); - _open_stdio(2, config_stderr(), O_WRONLY); - } + if (_root_dir.num_dirent("/")) + env.config([&] (Xml_node const &top) { + Xml_node const node = top.sub_node("libc"); + + try { + Genode::String path; + node.attribute("cwd").value(&path); + chdir(path.string()); + } catch (Xml_node::Nonexistent_attribute) { } + + _open_stdio(node, "stdin", 0, O_RDONLY); + _open_stdio(node, "stdout", 1, O_WRONLY); + _open_stdio(node, "stderr", 2, O_WRONLY); + }); } ~Vfs_plugin() { } diff --git a/repos/libports/src/lib/posix/construct.cc b/repos/libports/src/lib/posix/construct.cc index 90c347794a..8005e39e67 100644 --- a/repos/libports/src/lib/posix/construct.cc +++ b/repos/libports/src/lib/posix/construct.cc @@ -26,7 +26,7 @@ extern char **genode_envp; extern "C" int main(int argc, char ** argv, char **envp); -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { exit(main(genode_argc, genode_argv, genode_envp)); } diff --git a/repos/libports/src/server/fuse_fs/fuse_fs_main.cc b/repos/libports/src/server/fuse_fs/fuse_fs_main.cc index df17ea8278..942fb313f2 100644 --- a/repos/libports/src/server/fuse_fs/fuse_fs_main.cc +++ b/repos/libports/src/server/fuse_fs/fuse_fs_main.cc @@ -543,7 +543,7 @@ struct File_system::Main ** Component ** ***************/ -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { static File_system::Main inst(env.ep()); } diff --git a/repos/libports/src/test/ldso/main.cc b/repos/libports/src/test/ldso/main.cc index 8567d6657d..316912e3d4 100644 --- a/repos/libports/src/test/ldso/main.cc +++ b/repos/libports/src/test/ldso/main.cc @@ -185,7 +185,7 @@ static void test_shared_object_api(Env &env, Allocator &alloc) /** * Main function of LDSO test */ -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { static Heap heap(env.ram(), env.rm()); diff --git a/repos/libports/src/test/libports/main.cc b/repos/libports/src/test/libports/main.cc index 5522f65578..0111c2582f 100644 --- a/repos/libports/src/test/libports/main.cc +++ b/repos/libports/src/test/libports/main.cc @@ -13,4 +13,4 @@ #include -void Libc::Component::construct(Genode::Env &) { } +void Libc::Component::construct(Libc::Env &env) { } diff --git a/repos/os/src/test/blk/bench/main.cc b/repos/os/src/test/blk/bench/main.cc index 6217f6b689..573b23822e 100644 --- a/repos/os/src/test/blk/bench/main.cc +++ b/repos/os/src/test/blk/bench/main.cc @@ -154,7 +154,7 @@ struct Test::Main }; -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { static Test::Main server(env.ep()); } diff --git a/repos/ports/src/app/gdb_monitor/main.cc b/repos/ports/src/app/gdb_monitor/main.cc index af165f7888..0ef2359365 100644 --- a/repos/ports/src/app/gdb_monitor/main.cc +++ b/repos/ports/src/app/gdb_monitor/main.cc @@ -33,7 +33,7 @@ extern "C" int gdbserver_main(int argc, const char *argv[]); extern Genode::Env *genode_env; -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { genode_env = &env; diff --git a/repos/ports/src/app/openvpn/main.cc b/repos/ports/src/app/openvpn/main.cc index b8337c8ace..5c17880958 100644 --- a/repos/ports/src/app/openvpn/main.cc +++ b/repos/ports/src/app/openvpn/main.cc @@ -286,7 +286,7 @@ struct Main ** Component ** ***************/ -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { static Main server(env.ep()); } diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index 14eed4bc24..3d623bbce4 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -1262,4 +1262,4 @@ void Component::construct(Genode::Env &env) /** * Support for the noux/net version */ -void Libc::Component::construct(Genode::Env &env) { Component::construct(env); } +void Libc::Component::construct(Libc::Env &env) { Component::construct(env); } diff --git a/repos/ports/src/virtualbox/frontend/main.cc b/repos/ports/src/virtualbox/frontend/main.cc index 04e391bc78..a6f56fb86a 100644 --- a/repos/ports/src/virtualbox/frontend/main.cc +++ b/repos/ports/src/virtualbox/frontend/main.cc @@ -207,7 +207,7 @@ Genode::Env &genode_env() } -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { /* make Genode environment accessible via the global 'genode_env()' */ genode_env_ptr = &env; diff --git a/repos/ports/src/virtualbox5/frontend/main.cc b/repos/ports/src/virtualbox5/frontend/main.cc index da0e2ac1d0..c9810c6c58 100644 --- a/repos/ports/src/virtualbox5/frontend/main.cc +++ b/repos/ports/src/virtualbox5/frontend/main.cc @@ -238,7 +238,7 @@ Genode::Env &genode_env() } -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { /* make Genode environment accessible via the global 'genode_env()' */ genode_env_ptr = &env;