From bd3c53be31706e0b026dacf14a8dcf4e5ee1341d Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Mon, 21 May 2012 15:39:57 +0200 Subject: [PATCH] Implement LOG to Terminal adapter (issue #169) This commit adds a terminal_log component, and a run-script which demonstrates its usage. The terminal_log component provides the LOG service, and prints every log-output prefixed by the session-label via a terminal-session. --- gems/run/terminal_log.run | 160 +++++++++++++++++++++++++ os/src/server/terminal_log/main.cc | 167 +++++++++++++++++++++++++++ os/src/server/terminal_log/target.mk | 3 + 3 files changed, 330 insertions(+) create mode 100644 gems/run/terminal_log.run create mode 100644 os/src/server/terminal_log/main.cc create mode 100644 os/src/server/terminal_log/target.mk diff --git a/gems/run/terminal_log.run b/gems/run/terminal_log.run new file mode 100644 index 000000000..bc2da1502 --- /dev/null +++ b/gems/run/terminal_log.run @@ -0,0 +1,160 @@ +# +# \brief Showcases terminal_log server +# \author Stefan Kalkowski +# \date 2012-05-21 +# + +build { + core + init + drivers/framebuffer + drivers/input + drivers/pci + server/nitpicker + server/nit_fb + server/terminal + server/terminal_log +} +create_boot_directory + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + +} + +append_if [have_spec sdl] config { + + + + + + + + + + + + + + + + } + +append_if [have_spec pci] config { + + + + } + +append_if [have_spec vesa] config { + + + + + } + +append_if [have_spec pl11x] config { + + + + + } + +append_if [have_spec ps2] config { + + + + + } + +append_if [expr ! [have_spec sdl]] config { + + + + + + + + + } + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} +install_config $config + +# generic modules +set boot_modules { + core init + timer + nitpicker + launchpad + testnit + nit_fb + terminal + terminal_log +} + +# platform-specific modules +lappend_if [have_spec linux] boot_modules fb_sdl +lappend_if [have_spec pci] boot_modules pci_drv +lappend_if [have_spec vesa] boot_modules vesa_drv +lappend_if [have_spec ps2] boot_modules ps2_drv +lappend_if [have_spec pl11x] boot_modules pl11x_drv + +build_boot_image $boot_modules + +append qemu_args " -m 256 " +run_genode_until forever diff --git a/os/src/server/terminal_log/main.cc b/os/src/server/terminal_log/main.cc new file mode 100644 index 000000000..b5c426a01 --- /dev/null +++ b/os/src/server/terminal_log/main.cc @@ -0,0 +1,167 @@ +/* + * \brief LOG service that prints to a terminal + * \author Stefan Kalkowski + * \date 2012-05-21 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + + +namespace Genode { + + class Termlog_component : public Rpc_object + { + public: + + enum { LABEL_LEN = 64 }; + + private: + + char _label[LABEL_LEN]; + Terminal::Connection *_terminal; + + public: + + /** + * Constructor + */ + Termlog_component(const char *label, Terminal::Connection *terminal) + : _terminal(terminal) { snprintf(_label, LABEL_LEN, "[%s] ", label); } + + + /***************** + ** Log session ** + *****************/ + + /** + * Write a log-message to the terminal. + * + * The following function's code is a modified variant of the one in: + * 'base/src/core/include/log_session_component.h' + */ + size_t write(String const &string_buf) + { + if (!(string_buf.is_valid_string())) { + PERR("corrupted string"); + return 0; + } + + char const *string = string_buf.string(); + int len = strlen(string); + + /* + * Heuristic: The Log console implementation flushes + * the output preferably in front of escape + * sequences. If the line contains only + * the escape sequence, we skip the printing + * of the label and cut the line break (last + * character). + */ + enum { ESC = 27 }; + if ((string[0] == ESC) && (len == 5) && (string[4] == '\n')) { + char buf[5]; + strncpy(buf, string, 5); + _terminal->write(buf, len); + return len; + } + + _terminal->write(_label, strlen(_label)); + _terminal->write(string, len); + + /* if last character of string was not a line break, add one */ + if ((len > 0) && (string[len - 1] != '\n')) + _terminal->write("\n", 1); + + return len; + } + }; + + + class Termlog_root : public Root_component + { + private: + + Terminal::Connection *_terminal; + + protected: + + /** + * Root component interface + */ + Termlog_component *_create_session(const char *args) + { + size_t ram_quota = + Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); + + /* delete ram quota by the memory needed for the session */ + size_t session_size = max((size_t)4096, sizeof(Termlog_component)); + if (ram_quota < session_size) + throw Root::Quota_exceeded(); + + char label_buf[Termlog_component::LABEL_LEN]; + + Arg label_arg = Arg_string::find_arg(args, "label"); + label_arg.string(label_buf, sizeof(label_buf), ""); + + return new (md_alloc()) Termlog_component(label_buf, _terminal); + } + + public: + + /** + * Constructor + * + * \param session_ep entry point for managing cpu session objects + * \param md_alloc meta-data allocator to be used by root component + */ + Termlog_root(Rpc_entrypoint *session_ep, Allocator *md_alloc, + Terminal::Connection *terminal) + : Root_component(session_ep, md_alloc), + _terminal(terminal) { } + }; +} + + +int main(int argc, char **argv) +{ + using namespace Genode; + + /* + * Open Terminal session + */ + static Terminal::Connection terminal; + + /* + * Initialize server entry point + */ + enum { STACK_SIZE = 4096 }; + static Cap_connection cap; + static Rpc_entrypoint ep(&cap, STACK_SIZE, "termlog_ep"); + static Termlog_root termlog_root(&ep, env()->heap(), &terminal); + + /* + * Announce services + */ + env()->parent()->announce(ep.manage(&termlog_root)); + + /** + * Got to sleep forever + */ + sleep_forever(); + return 0; +} diff --git a/os/src/server/terminal_log/target.mk b/os/src/server/terminal_log/target.mk new file mode 100644 index 000000000..4f10baf19 --- /dev/null +++ b/os/src/server/terminal_log/target.mk @@ -0,0 +1,3 @@ +TARGET = terminal_log +SRC_CC = main.cc +LIBS = cxx env server signal