diff --git a/repos/gems/run/terminal_mux.run b/repos/gems/run/terminal_mux.run
deleted file mode 100644
index 84c7ccd107..0000000000
--- a/repos/gems/run/terminal_mux.run
+++ /dev/null
@@ -1,164 +0,0 @@
-#
-# \brief Example for using the terminal_mux server over UART
-# \author Norman Feske
-# \date 2013-02-20
-#
-
-assert_spec x86
-
-#
-# On Linux, we don't have a UART driver, on which this run script depends.
-#
-if {[have_spec linux]} { puts "Run script does not support Linux"; exit 0 }
-
-set build_components {
- core init noux lib/libc_noux app/cli_monitor test/bomb test/signal
- test/resource_yield timer drivers/uart server/terminal_mux
- server/terminal_log noux-pkg/vim
-}
-
-build $build_components
-
-create_boot_directory
-
-append config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-install_config $config
-
-
-#
-# Boot modules
-#
-
-# generic modules
-set boot_modules {
- core init timer ld.lib.so noux terminal_mux terminal_log
- test-signal cli_monitor test-resource_yield posix.lib.so
- libc.lib.so vfs.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so
- vim.tar pc_uart_drv
-}
-
-set fiasco_serial_esc_arg ""
-
-build_boot_image $boot_modules
-
-append qemu_args " -nographic "
-
-#
-# On all kernels, we write the core debug output to the kdb.log file,
-# and use qemu's stdio as the UART used by terminal_mux.
-#
-append qemu_args " -serial file:kdb.log "
-append qemu_args " -serial mon:stdio"
-
-run_genode_until forever
diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h
deleted file mode 100644
index 3550871d01..0000000000
--- a/repos/os/include/cli_monitor/child.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * \brief Child handling
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__CLI_MONITOR__CHILD_H_
-#define _INCLUDE__CLI_MONITOR__CHILD_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* CLI-monitor includes */
-#include
-
-namespace Cli_monitor { class Child_base; }
-
-
-class Cli_monitor::Child_base : public Genode::Child_policy
-{
- public:
-
- /*
- * XXX derive donated quota from information to be provided by
- * the used 'Connection' interfaces
- */
- enum { DONATED_RAM_QUOTA = 128*1024 };
-
- class Quota_exceeded : public Genode::Exception { };
-
- typedef Genode::size_t size_t;
- typedef Genode::Cap_quota Cap_quota;
-
- typedef Genode::Registered Parent_service;
-
- private:
-
- Genode::Env &_env;
-
- Ram &_ram;
-
- Genode::Allocator &_alloc;
-
- Genode::Session_label const _label;
- Binary_name const _binary_name;
-
- Genode::Pd_session_capability _ref_pd_cap;
- Genode::Pd_session &_ref_pd;
-
- Cap_quota _cap_quota;
-
- size_t _ram_quota;
- size_t _ram_limit;
-
- struct Parent_services : Genode::Registry
- {
- Genode::Allocator &_alloc;
- Parent_services(Genode::Allocator &alloc) : _alloc(alloc) { }
- ~Parent_services()
- {
- for_each([&] (Parent_service &s) { Genode::destroy(_alloc, &s); });
- }
- } _parent_services { _alloc };
-
- enum { ENTRYPOINT_STACK_SIZE = 12*1024 };
- Genode::Rpc_entrypoint _entrypoint;
-
- Genode::Child_policy_dynamic_rom_file _config_policy;
-
- /**
- * If set to true, immediately withdraw resources yielded by the child
- */
- bool _withdraw_on_yield_response = false;
-
- /**
- * Arguments of current resource request from the child
- */
- Genode::Parent::Resource_args _resource_args { };
-
- Genode::Signal_context_capability _yield_response_sigh_cap;
-
- Genode::Signal_context_capability _exit_sig_cap;
-
- /* true if child is scheduled for destruction */
- bool _exited = false;
-
- Genode::Child _child;
-
- Genode::Service &_matching_service(Genode::Service::Name const &name,
- Genode::Session_label const &label)
- {
- Genode::Service *service = nullptr;
-
- /* check for config file request */
- if ((service = _config_policy.resolve_session_request(name, label)))
- return *service;
-
- /* populate session-local parent service registry on demand */
- _parent_services.for_each([&] (Parent_service &s) {
- if (s.name() == name)
- service = &s; });
-
- if (service)
- return *service;
-
- return *new (_alloc) Parent_service(_parent_services, _env, name);
- }
-
- public:
-
- /**
- * Constructor
- *
- * \param ref_ram used as reference account for the child'd RAM
- * session and for allocating the backing store
- * for the child's configuration
- * \param alloc allocator used to fill parent-service registry
- * on demand
- */
- Child_base(Genode::Env &env,
- Ram &ram,
- Genode::Allocator &alloc,
- Name const &label,
- Binary_name const &binary_name,
- Genode::Pd_session &ref_pd,
- Genode::Pd_session_capability ref_pd_cap,
- Genode::Region_map &local_rm,
- Cap_quota cap_quota,
- Genode::size_t ram_quota,
- Genode::size_t ram_limit,
- Genode::Signal_context_capability yield_response_sig_cap,
- Genode::Signal_context_capability exit_sig_cap)
- :
- _env(env), _ram(ram), _alloc(alloc),
- _label(label), _binary_name(binary_name),
- _ref_pd_cap (ref_pd_cap), _ref_pd (ref_pd),
- _cap_quota(cap_quota), _ram_quota(ram_quota), _ram_limit(ram_limit),
- _entrypoint(&ref_pd, ENTRYPOINT_STACK_SIZE, _label.string(), false),
- _config_policy(local_rm, "config", _entrypoint, &_env.ram()),
- _yield_response_sigh_cap(yield_response_sig_cap),
- _exit_sig_cap(exit_sig_cap),
- _child(local_rm, _entrypoint, *this)
- { }
-
- Genode::Session_label label() const { return _label; }
-
- void configure(char const *config, size_t config_len)
- {
- _config_policy.load(config, config_len);
- }
-
- void start()
- {
- _entrypoint.activate();
- }
-
- /**
- * Issue yield request to the child
- */
- void yield(size_t amount, bool greedy)
- {
- if (requested_ram_quota())
- return; /* resource request in flight */
-
- char buf[128];
- Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", amount);
- _withdraw_on_yield_response = greedy;
- _child.yield(buf);
- }
-
- /**
- * Return amount of RAM currently requested by the child
- */
- size_t requested_ram_quota() const
- {
- return Genode::Arg_string::find_arg(_resource_args.string(), "ram_quota").ulong_value(0);
- }
-
- /**
- * Withdraw quota from the child
- *
- * \throw Ram::Transfer_quota_failed
- */
- void withdraw_ram_quota(size_t amount)
- {
- if (!amount)
- return;
-
- _ram.withdraw_from(_child.pd_session_cap(), amount);
- _ram_quota -= amount;
- }
-
- /**
- * Upgrade quota of child
- *
- * \throw Ram::Transfer_quota_failed
- */
- void upgrade_ram_quota(size_t amount)
- {
- _ram.transfer_to(_child.pd_session_cap(), amount);
- _ram_quota += amount;
-
- /* wake up child if resource request is in flight */
- size_t const req = requested_ram_quota();
- if (req && _child.pd().avail_ram().value >= req) {
- _child.notify_resource_avail();
-
- /* clear request state */
- _resource_args = Genode::Parent::Resource_args("");
- }
- }
-
- /**
- * Try to respond to a current resource request issued by the child
- *
- * This method evaluates the conditions, under which a resource
- * request can be answered: There must be enough room between the
- * current quota and the configured limit, and there must be enough
- * slack memory available. If both conditions are met, the quota
- * of the child gets upgraded.
- */
- void try_response_to_resource_request()
- {
- size_t const req = requested_ram_quota();
-
- if (!req)
- return; /* no resource request in flight */
-
- /*
- * Respond to the current request if the requested quota fits
- * within the limit and if there is enough free quota available.
- */
- if (req <= _ram.status().avail && req + _ram_quota <= _ram_limit) {
- try { upgrade_ram_quota(req); }
- catch (Ram::Transfer_quota_failed) { }
- }
- }
-
- /**
- * Set limit for on-demand RAM quota expansion
- */
- void ram_limit(size_t limit)
- {
- _ram_limit = limit;
- try_response_to_resource_request();
- }
-
- struct Ram_status
- {
- size_t quota = 0, limit = 0, xfer = 0, used = 0, avail = 0, req = 0;
-
- Ram_status() { }
- Ram_status(size_t quota, size_t limit, size_t xfer, size_t used,
- size_t avail, size_t req)
- :
- quota(quota), limit(limit), xfer(xfer), used(used),
- avail(avail), req(req)
- { }
- };
-
- /**
- * Return RAM quota status of the child
- *
- * XXX should be a const method, but the 'Pd_session' accessors
- * are not const
- */
- Ram_status ram_status()
- {
- return Ram_status(_ram_quota,
- _ram_limit,
- _ram_quota - _child.pd().ram_quota().value,
- _child.pd().used_ram().value,
- _child.pd().avail_ram().value,
- requested_ram_quota());
- }
-
- /**
- * Return true if child exited and should be destructed
- */
- bool exited() const { return _exited; }
-
-
- /****************************
- ** Child_policy interface **
- ****************************/
-
- Name name() const override { return _label; }
- Binary_name binary_name() const override { return _binary_name; }
-
- Genode::Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
- Genode::Pd_session &ref_pd() override { return _ref_pd; }
-
- void init(Genode::Pd_session &session, Genode::Pd_session_capability cap) override
- {
- session.ref_account(_ref_pd_cap);
- _ref_pd.transfer_quota(cap, _cap_quota);
- _ref_pd.transfer_quota(cap, Genode::Ram_quota{_ram_quota});
- }
-
- Route resolve_session_request(Genode::Service::Name const &name,
- Genode::Session_label const &label) override
- {
- return Route { .service = _matching_service(name, label),
- .label = label,
- .diag = Genode::Session::Diag() };
- }
-
- void yield_response() override
- {
- if (_withdraw_on_yield_response) {
- enum { RESERVE = 4*1024*1024 };
-
- size_t amount = _child.pd().avail_ram().value < RESERVE
- ? 0 : _child.pd().avail_ram().value - RESERVE;
-
- /* try to immediately withdraw freed-up resources */
- try { withdraw_ram_quota(amount); }
- catch (Ram::Transfer_quota_failed) { }
- }
-
- /* propagate yield-response signal */
- Genode::Signal_transmitter(_yield_response_sigh_cap).submit();
- }
-
- void resource_request(Genode::Parent::Resource_args const &args) override
- {
- _resource_args = args;
- try_response_to_resource_request();
- }
-
- void exit(int exit_value) override
- {
- Genode::log("subsystem \"", name(), "\" exited with value ", exit_value);
- _exited = true;
-
- /* trigger destruction of the child */
- Genode::Signal_transmitter(_exit_sig_cap).submit();
- }
-};
-
-#endif /* _INCLUDE__CLI_MONITOR__CHILD_H_ */
diff --git a/repos/os/include/cli_monitor/ram.h b/repos/os/include/cli_monitor/ram.h
deleted file mode 100644
index 7f6a42ae2a..0000000000
--- a/repos/os/include/cli_monitor/ram.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * \brief RAM management
- * \author Norman Feske
- * \date 2013-10-14
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__CLI_MONITOR__RAM_H_
-#define _INCLUDE__CLI_MONITOR__RAM_H_
-
-/* Genode includes */
-#include
-
-namespace Cli_monitor { class Ram; }
-
-
-class Cli_monitor::Ram
-{
- private:
-
- typedef Genode::size_t size_t;
-
- Genode::Pd_session &_pd;
- Genode::Pd_session_capability _pd_cap;
-
- Genode::Lock mutable _lock { };
-
- Genode::Signal_context_capability _yield_sigh;
- Genode::Signal_context_capability _resource_avail_sigh;
-
- size_t _preserve;
-
- void _validate_preservation()
- {
- if (_pd.avail_ram().value < _preserve)
- Genode::Signal_transmitter(_yield_sigh).submit();
-
- /* verify to answer outstanding resource requests too */
- if (_pd.avail_ram().value > _preserve)
- Genode::Signal_transmitter(_resource_avail_sigh).submit();
- }
-
- public:
-
- struct Status
- {
- size_t quota, used, avail, preserve;
- Status(size_t quota, size_t used, size_t avail, size_t preserve)
- : quota(quota), used(used), avail(avail), preserve(preserve) { }
- };
-
- Ram(Genode::Pd_session &pd,
- Genode::Pd_session_capability pd_cap,
- size_t preserve,
- Genode::Signal_context_capability yield_sigh,
- Genode::Signal_context_capability resource_avail_sigh)
- :
- _pd(pd), _pd_cap(pd_cap),
- _yield_sigh(yield_sigh),
- _resource_avail_sigh(resource_avail_sigh),
- _preserve(preserve)
- { }
-
- size_t preserve() const
- {
- Genode::Lock::Guard guard(_lock);
-
- return _preserve;
- }
-
- void preserve(size_t preserve)
- {
- Genode::Lock::Guard guard(_lock);
-
- _preserve = preserve;
-
- _validate_preservation();
- }
-
- Status status() const
- {
- Genode::Lock::Guard guard(_lock);
-
- return Status(_pd.ram_quota().value, _pd.used_ram().value,
- _pd.avail_ram().value, _preserve);
- }
-
- void validate_preservation()
- {
- Genode::Lock::Guard guard(_lock);
-
- _validate_preservation();
- }
-
- /**
- * Exception type
- */
- class Transfer_quota_failed { };
-
- /**
- * \throw Transfer_quota_failed
- */
- void withdraw_from(Genode::Pd_session_capability from, size_t amount)
- {
- using namespace Genode;
-
- Lock::Guard guard(_lock);
-
- try { Pd_session_client(from).transfer_quota(_pd_cap, Ram_quota{amount}); }
- catch (...) { throw Transfer_quota_failed(); }
-
- Signal_transmitter(_resource_avail_sigh).submit();
- }
-
- /**
- * \throw Transfer_quota_failed
- */
- void transfer_to(Genode::Pd_session_capability to, size_t amount)
- {
- Genode::Lock::Guard guard(_lock);
-
- if (_pd.avail_ram().value < (_preserve + amount)) {
- Genode::Signal_transmitter(_yield_sigh).submit();
- throw Transfer_quota_failed();
- }
-
- try { _pd.transfer_quota(to, Genode::Ram_quota{amount}); }
- catch (...) { throw Transfer_quota_failed(); }
- }
-
- size_t avail() const { return _pd.avail_ram().value; }
-};
-
-#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */
diff --git a/repos/os/src/app/cli_monitor/child.h b/repos/os/src/app/cli_monitor/child.h
deleted file mode 100644
index 755c3241ce..0000000000
--- a/repos/os/src/app/cli_monitor/child.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * \brief Child carrying application-specific context information
- * \author Norman Feske
- * \date 2014-10-02
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _CHILD_H_
-#define _CHILD_H_
-
-/* public CLI-monitor includes */
-#include
-
-/* local includes */
-#include
-
-namespace Cli_monitor { struct Child; }
-
-
-struct Cli_monitor::Child : Child_base, private List::Element
-{
- friend class List;
-
- using List::Element::next;
-
- Argument argument;
-
- Child(Genode::Env &env,
- Ram &ram,
- Genode::Allocator &alloc,
- Name const &label,
- Binary_name const &binary,
- Genode::Pd_session &ref_pd,
- Genode::Pd_session_capability ref_pd_cap,
- Genode::Region_map &local_rm,
- Cap_quota cap_quota,
- Genode::size_t ram_quota,
- Genode::size_t ram_limit,
- Genode::Signal_context_capability yield_response_sig_cap,
- Genode::Signal_context_capability exit_sig_cap)
- :
- Child_base(env,
- ram,
- alloc,
- label,
- binary,
- ref_pd,
- ref_pd_cap,
- local_rm,
- cap_quota,
- ram_quota,
- ram_limit,
- yield_response_sig_cap,
- exit_sig_cap),
- argument(label.string(), "subsystem")
- { }
-};
-
-#endif /* _CHILD_H_ */
diff --git a/repos/os/src/app/cli_monitor/child_registry.h b/repos/os/src/app/cli_monitor/child_registry.h
deleted file mode 100644
index abc8c2794e..0000000000
--- a/repos/os/src/app/cli_monitor/child_registry.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * \brief Registry of running children
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _CHILD_REGISTRY_H_
-#define _CHILD_REGISTRY_H_
-
-/* Genode includes */
-#include
-
-/* local includes */
-#include
-
-namespace Cli_monitor { class Child_registry; }
-
-
-class Cli_monitor::Child_registry : public List
-{
- private:
-
- /**
- * Return true if a child with the specified name already exists
- */
- bool _child_name_exists(const char *label)
- {
- for (Child *child = first() ; child; child = child->next())
- if (child->name() == label)
- return true;
- return false;
- }
-
- public:
-
- enum { CHILD_NAME_MAX_LEN = 64 };
-
- /**
- * Produce new unique child name
- */
- void unique_child_name(const char *prefix, char *dst, int dst_len)
- {
- char buf[CHILD_NAME_MAX_LEN];
- char suffix[8];
- suffix[0] = 0;
-
- for (int cnt = 1; true; cnt++) {
-
- /* build program name composed of prefix and numeric suffix */
- snprintf(buf, sizeof(buf), "%s%s", prefix, suffix);
-
- /* if such a program name does not exist yet, we are happy */
- if (!_child_name_exists(buf)) {
- strncpy(dst, buf, dst_len);
- return;
- }
-
- /* increase number of suffix */
- snprintf(suffix, sizeof(suffix), ".%d", cnt + 1);
- }
- }
-
- /**
- * Call functor 'fn' for each child
- *
- * The functor receives the child name as 'char const *'.
- */
- template
- void for_each_child_name(FN const &fn) const
- {
- for (Child const *child = first() ; child; child = child->next())
- fn(child->name());
- }
-};
-
-#endif /* _CHILD_REGISTRY_H_ */
diff --git a/repos/os/src/app/cli_monitor/command_line.h b/repos/os/src/app/cli_monitor/command_line.h
deleted file mode 100644
index 5016e63bfb..0000000000
--- a/repos/os/src/app/cli_monitor/command_line.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * \brief Utility for command-line parsing
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _COMMAND_LINE_H_
-#define _COMMAND_LINE_H_
-
-#include
-
-namespace Cli_monitor { class Command_line; }
-
-
-class Cli_monitor::Command_line
-{
- private:
-
- char const *_cmd_line;
- Command &_command;
-
- bool _parameter_is_known(Token token)
- {
- return Argument_tracker::lookup(token, _command.parameters()) != 0;
- }
-
- Token _tag_token(char const *tag)
- {
- for (Token token(_cmd_line); token; token = token.next())
- if (strcmp(token.start(), tag, token.len()) == 0
- && strlen(tag) == token.len()
- && _parameter_is_known(token))
- return token;
-
- return Token();
- }
-
- Token _value_token(char const *tag)
- {
- return _tag_token(tag).next().next();
- }
-
- static bool _is_parameter(Token token)
- {
- return token[0] == '-' && token[1] == '-';
- }
-
-
- public:
-
- /**
- * Constructor
- *
- * \param cmd_line null-terminated command line string
- * \param command meta data about the command
- */
- Command_line(char const *cmd_line, Command &command)
- : _cmd_line(cmd_line), _command(command) { }
-
- /**
- * Return true if tag is specified at the command line
- */
- bool parameter_exists(char const *tag)
- {
- return _tag_token(tag);
- }
-
- /**
- * Return number argument specified for the given tag
- */
- template
- bool parameter(char const *tag, T &result)
- {
- Token value = _value_token(tag);
- return value && Genode::ascii_to(value.start(), result) != 0;
- }
-
- /**
- * Return string argument specified for the given tag
- */
- bool parameter(char const *tag, char *result, size_t result_len)
- {
- Token value = _value_token(tag);
- if (!value)
- return false;
-
- value.string(result, result_len);
- return true;
- }
-
- bool argument(unsigned index, char *result, size_t result_len)
- {
- Argument_tracker argument_tracker(_command);
-
- /* argument counter */
- unsigned cnt = 0;
-
- for (Token token(_cmd_line); token; token = token.next()) {
-
- argument_tracker.supply_token(token);
-
- if (!argument_tracker.valid())
- return false;
-
- if (!argument_tracker.expect_arg())
- continue;
-
- Token arg = token.next();
- if (!arg)
- return false;
-
- /*
- * The 'arg' token could either the tag of a parameter or
- * an argument. We only want to count the arguments. So
- * we skip tokens that have the usual form a parameter tag.
- */
- if (_is_parameter(arg))
- continue;
-
- if (cnt == index) {
- arg.string(result, result_len);
- return true;
- }
- cnt++;
- }
- return false;
- }
-
- /**
- * Validate parameter tags
- *
- * \return tag token of first unexpected parameter, or
- * invalid token if no unexpected parameter was found
- */
- Token unexpected_parameter()
- {
- Argument_tracker argument_tracker(_command);
-
- for (Token token(_cmd_line); token; token = token.next()) {
-
- argument_tracker.supply_token(token);
-
- if (!argument_tracker.valid())
- return token;
-
- if (!argument_tracker.expect_arg())
- continue;
-
- Token arg = token.next();
-
- /* ignore non-parameter tokens (i.e., normal arguments) */
- if (!_is_parameter(arg))
- continue;
-
- /* if parameter with the given tag exists, we are fine */
- if (_parameter_is_known(arg))
- continue;
-
- /* we hit an unknown parameter tag */
- return arg;
- }
- return Token();
- }
-};
-
-#endif /* _COMMAND_LINE_H_ */
diff --git a/repos/os/src/app/cli_monitor/format_util.h b/repos/os/src/app/cli_monitor/format_util.h
deleted file mode 100644
index cd3a9feb1f..0000000000
--- a/repos/os/src/app/cli_monitor/format_util.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * \brief Utilities for formatting output to terminal
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _FORMAT_UTIL_H_
-#define _FORMAT_UTIL_H_
-
-/* local includes */
-#include
-
-namespace Cli_monitor {
-
- /**
- * Print rational number with two fractional decimals
- */
- static inline size_t format_number(char *dst, size_t len, size_t const value,
- size_t const quotient, char const *unit)
- {
- size_t const integer = value / quotient;
- size_t const n = snprintf(dst, len, "%ld.", integer);
- size_t const remainder = ((value - (integer * quotient))*100) / quotient;
-
- if (len == n) return n;
-
- return n + snprintf(dst + n, len - n, "%s%ld%s",
- remainder < 10 ? "0" : "", remainder, unit);
- }
-
-
- /**
- * Print number of bytes using the best suitable unit
- */
- static inline size_t format_bytes(char *dst, size_t len, size_t bytes)
- {
- enum { KB = 1024, MB = 1024*KB };
-
- if (bytes > MB)
- return format_number(dst, len, bytes, MB, " MiB");
-
- if (bytes > KB)
- return format_number(dst, len, bytes, KB, " KiB");
-
- return snprintf(dst, len, "%ld bytes", bytes);
- }
-
-
- /**
- * Print number in MiB, without unit
- */
- static inline size_t format_mib(char *dst, size_t len, size_t bytes)
- {
- enum { KB = 1024, MB = 1024*KB };
-
- return format_number(dst, len, bytes, MB , "");
- }
-
-
- static inline size_t format_bytes(size_t bytes)
- {
- char buf[128];
- return format_bytes(buf, sizeof(buf), bytes);
- }
-
-
- static inline size_t format_mib(size_t bytes)
- {
- char buf[128];
- return format_mib(buf, sizeof(buf), bytes);
- }
-
-
- static inline void tprint_bytes(Terminal::Session &terminal, size_t bytes)
- {
- char buf[128];
- format_bytes(buf, sizeof(buf), bytes);
- Terminal::tprintf(terminal, "%s", buf);
- }
-
-
- static inline void tprint_mib(Terminal::Session &terminal, size_t bytes)
- {
- char buf[128];
- format_mib(buf, sizeof(buf), bytes);
- Terminal::tprintf(terminal, "%s", buf);
- }
-
-
- static inline void tprint_status_bytes(Terminal::Session &terminal,
- char const *label, size_t bytes)
- {
- Terminal::tprintf(terminal, label);
- tprint_bytes(terminal, bytes);
- Terminal::tprintf(terminal, "\n");
- }
-
-
- static void tprint_padding(Terminal::Session &terminal, size_t pad, char c = ' ')
- {
- char const buf[2] = { c, 0 };
- for (unsigned i = 0; i < pad; i++)
- Terminal::tprintf(terminal, buf);
- }
-}
-
-#endif /* _FORMAT_UTIL_H_ */
diff --git a/repos/os/src/app/cli_monitor/help_command.h b/repos/os/src/app/cli_monitor/help_command.h
deleted file mode 100644
index 691ed30cd9..0000000000
--- a/repos/os/src/app/cli_monitor/help_command.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * \brief Help command
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _HELP_COMMAND_H_
-#define _HELP_COMMAND_H_
-
-namespace Cli_monitor { struct Help_command; }
-
-
-struct Cli_monitor::Help_command : Command
-{
- Help_command() : Command("help", "brief help information") { }
-
- void execute(Command_line &, Terminal::Session &terminal) override
- {
- tprintf(terminal, " Press [tab] for a list of commands.\n");
- tprintf(terminal, " When given a command, press [tab] for a list of arguments.\n");
- }
-};
-
-#endif /* _HELP_COMMAND_H_ */
diff --git a/repos/os/src/app/cli_monitor/kill_command.h b/repos/os/src/app/cli_monitor/kill_command.h
deleted file mode 100644
index bd88756250..0000000000
--- a/repos/os/src/app/cli_monitor/kill_command.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * \brief Kill command
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _KILL_COMMAND_H_
-#define _KILL_COMMAND_H_
-
-/* local includes */
-#include
-
-namespace Cli_monitor { struct Kill_command; }
-
-
-struct Cli_monitor::Kill_command : Command
-{
- Child_registry &_children;
-
- Genode::Allocator &_alloc;
-
- Parameter _kill_all_param { "--all", Parameter::VOID, "kill all subsystems" };
-
- void _destroy_child(Child *child, Terminal::Session &terminal)
- {
- tprintf(terminal, "destroying subsystem '%s'\n", child->name().string());
- _children.remove(child);
- Genode::destroy(_alloc, child);
- }
-
- Kill_command(Child_registry &children, Genode::Allocator &alloc)
- :
- Command("kill", "destroy subsystem"), _children(children), _alloc(alloc)
- {
- add_parameter(_kill_all_param);
- }
-
- void _for_each_argument(Argument_fn const &fn) const override
- {
- auto child_name_fn = [&] (Child_base::Name const &child_name) {
- Argument arg(child_name.string(), "");
- fn(arg);
- };
-
- _children.for_each_child_name(child_name_fn);
- }
-
- void execute(Command_line &cmd, Terminal::Session &terminal) override
- {
- bool const kill_all = cmd.parameter_exists("--all");
-
- if (kill_all) {
- for (Child *child = _children.first(); child; child = _children.first())
- _destroy_child(child, terminal);
- return;
- }
-
- char label[128];
- label[0] = 0;
- if (cmd.argument(0, label, sizeof(label)) == false) {
- tprintf(terminal, "Error: no subsystem name specified\n");
- return;
- }
-
- /* lookup child by its unique name */
- for (Child *child = _children.first(); child; child = child->next()) {
- if (child->name() == label) {
- _destroy_child(child, terminal);
- return;
- }
- }
-
- tprintf(terminal, "Error: subsystem '%s' does not exist\n", label);
- }
-};
-
-#endif /* _KILL_COMMAND_H_ */
diff --git a/repos/os/src/app/cli_monitor/line_editor.h b/repos/os/src/app/cli_monitor/line_editor.h
deleted file mode 100644
index 1fbcd09afc..0000000000
--- a/repos/os/src/app/cli_monitor/line_editor.h
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- * \brief Line editor for command-line interfaces
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _LINE_EDITOR_H_
-#define _LINE_EDITOR_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace Cli_monitor {
-
- using Genode::List;
- using Genode::max;
- using Genode::strlen;
- using Genode::strncpy;
- using Genode::snprintf;
- using Genode::strcmp;
- using Genode::size_t;
- using Genode::off_t;
- using Genode::Interface;
-
- struct Completable;
- struct Argument;
- struct Parameter;
- struct Command_line;
- struct Command;
- struct Command_registry;
- struct Scanner_policy;
- struct Argument_tracker;
- struct Line_editor;
-
- typedef Genode::Token Token;
-}
-
-
-struct Cli_monitor::Completable
-{
- typedef Genode::String<64> Name;
- typedef Genode::String<160> Short_help;
-
- Name const _name;
- Short_help const _short_help;
-
- Name name() const { return _name; }
- Short_help short_help() const { return _short_help; }
-
- Completable(char const *name, char const *short_help)
- : _name(name), _short_help(short_help) { }
-};
-
-
-/**
- * Representation of normal command-line argument
- */
-struct Cli_monitor::Argument : Completable
-{
- Argument(char const *name, char const *short_help)
- : Completable(name, short_help) { }
-
- char const *name_suffix() const { return ""; }
-};
-
-
-/**
- * Representation of a parameter of the form '--tag value'
- */
-struct Cli_monitor::Parameter : List::Element, Completable
-{
- enum Type { IDENT, NUMBER, VOID };
-
- Type const _type;
-
- Parameter(char const *name, Type type, char const *short_help)
- :
- Completable(name, short_help), _type(type)
- { }
-
- bool needs_value() const { return _type != VOID; }
-
- char const *name_suffix() const
- {
- switch (_type) {
- case IDENT: return "";
- case NUMBER: return "";
- case VOID: return "";
- }
- return "";
- }
-};
-
-
-/**
- * Representation of a command that can have arguments and parameters
- */
-struct Cli_monitor::Command : private List::Element,
- private Completable
-{
- List _parameters { };
-
- friend class List;
-
- using List::Element::next;
- using Completable::name;
- using Completable::short_help;
-
- /**
- * Functor that takes a command 'Argument' object as argument
- */
- struct Argument_fn : Interface
- {
- virtual void operator () (Argument const &) const = 0;
- };
-
- Command(char const *name, char const *short_help)
- : Completable(name, short_help) { }
-
- virtual ~Command() { }
-
- void add_parameter(Parameter &par) { _parameters.insert(&par); }
-
- char const *name_suffix() const { return ""; }
-
- List ¶meters() { return _parameters; }
-
- virtual void execute(Command_line &, Terminal::Session &terminal) = 0;
-
- /**
- * Command-specific support for 'for_each_argument'
- */
- virtual void _for_each_argument(Argument_fn const &) const { };
-
- /**
- * Execute functor 'fn' for each command argument
- */
- template
- void for_each_argument(FN const &fn) const
- {
- struct _Fn : Argument_fn
- {
- FN const &fn;
- void operator () (Argument const &arg) const override { fn(arg); }
- _Fn(FN const &fn) : fn(fn) { }
- } _fn(fn);
-
- _for_each_argument(_fn);
- }
-};
-
-
-struct Cli_monitor::Command_registry : List { };
-
-
-/**
- * Scanner policy that accepts '-', '.' and '_' as valid identifier characters
- */
-struct Cli_monitor::Scanner_policy
-{
- static bool identifier_char(char c, unsigned i)
- {
- return Genode::is_letter(c) || (c == '_') || (c == '-') || (c == '.')
- || (i && Genode::is_digit(c));
- }
-};
-
-
-/**
- * State machine used for sequentially parsing command-line arguments
- */
-struct Cli_monitor::Argument_tracker
-{
- private:
-
- Command &_command;
-
- enum State { EXPECT_COMMAND, EXPECT_SPACE_BEFORE_ARG, EXPECT_ARG,
- EXPECT_SPACE_BEFORE_VAL, EXPECT_VAL, INVALID };
-
- State _state;
-
- /**
- * Return true if there is exactly one complete match and no additional
- * partial matches
- */
- static bool _one_matching_argument(char const *str, size_t str_len,
- Command const &command)
- {
- unsigned complete_cnt = 0, partial_cnt = 0;
-
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0) {
- partial_cnt++;
-
- if (strlen(arg.name().string()) == str_len)
- complete_cnt++;
- }
- };
-
- command.for_each_argument(argument_fn);
-
- return partial_cnt == 1 && complete_cnt == 1;
- }
-
- public:
-
- Argument_tracker(Command &command)
- : _command(command), _state(EXPECT_COMMAND) { }
-
- template
- static T *lookup(char const *str, size_t str_len,
- List &list)
- {
- Token tag(str, str_len);
- for (T *curr = list.first(); curr; curr = curr->next())
- if (strcmp(tag.start(), curr->name().string(), tag.len()) == 0
- && strlen(curr->name().string()) == tag.len())
- return curr;
-
- return 0;
- }
-
- template
- static T *lookup(Token token, List &list)
- {
- return lookup(token.start(), token.len(), list);
- }
-
- void supply_token(Token token, bool token_may_be_incomplete = false)
- {
- switch (_state) {
-
- case INVALID: break;
-
- case EXPECT_COMMAND:
-
- if (token.type() == Token::IDENT) {
- _state = EXPECT_SPACE_BEFORE_ARG;
- break;
- }
- _state = INVALID;
- break;
-
- case EXPECT_SPACE_BEFORE_ARG:
-
- if (token.type() == Token::WHITESPACE)
- _state = EXPECT_ARG;
- break;
-
- case EXPECT_ARG:
-
- if (token.type() == Token::IDENT) {
-
- Parameter *parameter =
- lookup(token.start(), token.len(), _command.parameters());
-
- if (parameter && parameter->needs_value()) {
- _state = EXPECT_SPACE_BEFORE_VAL;
- break;
- }
-
- if (!token_may_be_incomplete
- || _one_matching_argument(token.start(), token.len(), _command))
- _state = EXPECT_SPACE_BEFORE_ARG;
- }
- break;
-
- case EXPECT_SPACE_BEFORE_VAL:
-
- if (token.type() == Token::WHITESPACE)
- _state = EXPECT_VAL;
- break;
-
- case EXPECT_VAL:
-
- if (token.type() == Token::IDENT
- || token.type() == Token::NUMBER) {
-
- _state = EXPECT_SPACE_BEFORE_ARG;
- }
- break;
- }
- }
-
- bool valid() const { return _state != INVALID; }
- bool expect_arg() const { return _state == EXPECT_ARG; }
- bool expect_space() const { return _state == EXPECT_SPACE_BEFORE_ARG
- || _state == EXPECT_SPACE_BEFORE_VAL; }
-};
-
-
-/**
- * Editing and completion logic
- */
-class Cli_monitor::Line_editor
-{
- private:
-
- char const *_prompt;
- size_t const _prompt_len;
- char * const _buf;
- size_t const _buf_size;
- unsigned _cursor_pos = 0;
- Terminal::Session &_terminal;
- Command_registry &_commands;
- bool _complete = false;
-
- /**
- * State tracker for escape sequences within user input
- *
- * This tracker is used to decode special keys (e.g., cursor keys).
- */
- struct Seq_tracker
- {
- enum State { INIT, GOT_ESC, GOT_FIRST } _state = INIT;
- char _normal = 0, _first = 0, _second = 0;
- bool _sequence_complete { false };
-
- Seq_tracker() { }
-
- void input(char c)
- {
- switch (_state) {
- case INIT:
- if (c == 27)
- _state = GOT_ESC;
- else
- _normal = c;
- _sequence_complete = false;
- break;
-
- case GOT_ESC:
- _first = c;
- _state = GOT_FIRST;
- break;
-
- case GOT_FIRST:
- _second = c;
- _state = INIT;
- _sequence_complete = true;
- break;
- }
- }
-
- bool normal() const { return _state == INIT && !_sequence_complete; }
-
- char normal_char() const { return _normal; }
-
- bool _fn_complete(char match_first, char match_second) const
- {
- return _sequence_complete
- && _first == match_first
- && _second == match_second;
- }
-
- bool key_up() const { return _fn_complete(91, 65); }
- bool key_down() const { return _fn_complete(91, 66); }
- bool key_right() const { return _fn_complete(91, 67); }
- bool key_left() const { return _fn_complete(91, 68); }
- bool key_delete() const { return _fn_complete(91, 51); }
- };
-
- Seq_tracker _seq_tracker { };
-
- void _write(char c) { _terminal.write(&c, sizeof(c)); }
-
- void _write(char const *s) { _terminal.write(s, strlen(s)); }
-
- void _write_spaces(unsigned num)
- {
- for (unsigned i = 0; i < num; i++)
- _write(' ');
- }
-
- void _write_newline() { _write(10); }
-
- void _clear_until_end_of_line() { _write("\e[K "); }
-
- void _move_cursor_to(unsigned pos)
- {
- char seq[10];
- snprintf(seq, sizeof(seq), "\e[%ldG", pos + _prompt_len);
- _write(seq);
- }
-
- void _delete_character()
- {
- strncpy(&_buf[_cursor_pos], &_buf[_cursor_pos + 1], _buf_size);
-
- _move_cursor_to(_cursor_pos);
- _write(&_buf[_cursor_pos]);
- _clear_until_end_of_line();
- _move_cursor_to(_cursor_pos);
- }
-
- void _insert_character(char c)
- {
- /* insert regular character */
- if (_cursor_pos >= _buf_size - 1)
- return;
-
- /* make room in the buffer */
- for (unsigned i = _buf_size - 1; i > _cursor_pos; i--)
- _buf[i] = _buf[i - 1];
- _buf[_cursor_pos] = c;
-
- /* update terminal */
- _write(&_buf[_cursor_pos]);
- _cursor_pos++;
- _move_cursor_to(_cursor_pos);
- }
-
- void _fresh_prompt()
- {
- _write(_prompt);
- _write(_buf);
- _move_cursor_to(_cursor_pos);
- }
-
- void _handle_key()
- {
- enum { BACKSPACE = 8,
- TAB = 9,
- LINE_FEED = 10,
- CARRIAGE_RETURN = 13 };
-
- if (_seq_tracker.key_left()) {
- if (_cursor_pos > 0) {
- _cursor_pos--;
- _write(BACKSPACE);
- }
- return;
- }
-
- if (_seq_tracker.key_right()) {
- if (_cursor_pos < strlen(_buf)) {
- _cursor_pos++;
- _move_cursor_to(_cursor_pos);
- }
- return;
- }
-
- if (_seq_tracker.key_delete())
- _delete_character();
-
- if (!_seq_tracker.normal())
- return;
-
- char const c = _seq_tracker.normal_char();
-
- if (c == TAB) {
- _perform_completion();
- return;
- }
-
- if (c == CARRIAGE_RETURN || c == LINE_FEED) {
- if (strlen(_buf) > 0) {
- _write(LINE_FEED);
- _complete = true;
- }
- return;
- }
-
- if (c == BACKSPACE) {
- if (_cursor_pos > 0) {
- _cursor_pos--;
- _delete_character();
- }
- return;
- }
-
- if (c == 126)
- return;
-
- _insert_character(c);
- }
-
- template
- COMPLETABLE *_lookup_matching(char const *str, size_t str_len,
- List &list)
- {
- Token tag(str, str_len);
- COMPLETABLE *curr = list.first();
- for (; curr; curr = curr->next()) {
- if (strcmp(tag.start(), curr->name(), tag.len()) == 0
- && strlen(curr->name()) == tag.len())
- return curr;
- }
- return nullptr;
- }
-
- Command *_lookup_matching_command()
- {
- Token cmd(_buf, _cursor_pos);
- for (Command *curr = _commands.first(); curr; curr = curr->next())
- if (strcmp(cmd.start(), curr->name().string(), cmd.len()) == 0
- && _cursor_pos > cmd.len())
- return curr;
- return nullptr;
- }
-
- template
- unsigned _num_partial_matches(char const *str, size_t str_len, List &list)
- {
- Token token(str, str_len);
-
- unsigned num_partial_matches = 0;
- for (T *curr = list.first(); curr; curr = curr->next()) {
- if (strcmp(token.start(), curr->name().string(), token.len()) != 0)
- continue;
-
- num_partial_matches++;
- }
- return num_partial_matches;
- }
-
- unsigned _num_matching_arguments(char const *str, size_t str_len,
- Command const &command) const
- {
- unsigned num_matches = 0;
-
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0)
- num_matches++;
- };
-
- command.for_each_argument(argument_fn);
-
- return num_matches;
- }
-
- /**
- * Determine the name-column width of list of partial matches
- */
- template
- size_t _width_of_partial_matches(char const *str, size_t str_len,
- List &list)
- {
- Token token(str, str_len);
-
- size_t max_name_len = 0;
- for (T *curr = list.first(); curr; curr = curr->next()) {
- if (strcmp(token.start(), curr->name().string(), token.len()) != 0)
- continue;
-
- size_t const name_len = strlen(curr->name().string())
- + strlen(curr->name_suffix());
- max_name_len = max(max_name_len, name_len);
- }
- return max_name_len;
- }
-
- unsigned _width_of_matching_arguments(char const *str, size_t str_len,
- Command const &command) const
- {
- size_t max_name_len = 0;
-
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0) {
- size_t const name_len = strlen(arg.name().string());
- if (name_len > max_name_len)
- max_name_len = name_len;
- }
- };
-
- command.for_each_argument(argument_fn);
-
- return max_name_len;
- }
-
- template
- char const *_any_partial_match_name(char const *str, size_t str_len,
- List &list)
- {
- Token token(str, str_len);
-
- for (T *curr = list.first(); curr; curr = curr->next())
- if (strcmp(token.start(), curr->name().string(), token.len()) == 0)
- return curr->name().string();
-
- return 0;
- }
-
- Argument::Name _any_matching_argument(char const *str, size_t str_len,
- Command const &command) const
- {
- Argument::Name name;
-
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0)
- name = arg.name();
- };
-
- command.for_each_argument(argument_fn);
-
- return name;
- }
-
- template
- void _list_partial_matches(char const *str, size_t str_len,
- unsigned pad, List &list)
- {
- Token token(str, str_len);
-
- for (T *curr = list.first(); curr; curr = curr->next()) {
- if (strcmp(token.start(), curr->name().string(), token.len()) != 0)
- continue;
-
- _write_newline();
- _write_spaces(2);
- _write(curr->name().string());
- _write_spaces(1);
- _write(curr->name_suffix());
-
- /* pad short help with whitespaces */
- size_t const name_len = strlen(curr->name().string())
- + strlen(curr->name_suffix());
- _write_spaces(pad + 3 - name_len);
- _write(curr->short_help().string());
- }
- }
-
- void _list_matching_arguments(char const *str, size_t str_len,
- unsigned pad, Command const &command)
- {
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0) {
-
- _write_newline();
- _write_spaces(2);
- _write(arg.name().string());
- _write_spaces(1);
- _write(arg.name_suffix());
-
- /* pad short help with whitespaces */
- size_t const name_len = strlen(arg.name().string())
- + strlen(arg.name_suffix());
- _write_spaces(pad + 3 - name_len);
- _write(arg.short_help().string());
- }
- };
-
- command.for_each_argument(argument_fn);
- }
-
- template
- void _do_completion(char const *str, size_t str_len, List &list)
- {
- Token token(str, str_len);
-
- /* look up completable token */
- T *partial_match = 0;
- for (T *curr = list.first(); curr; curr = curr->next()) {
- if (strcmp(token.start(), curr->name().string(), token.len()) == 0) {
- partial_match = curr;
- break;
- }
- }
-
- if (!partial_match)
- return;
-
- for (unsigned i = token.len(); i < strlen(partial_match->name().string()); i++)
- _insert_character(partial_match->name().string()[i]);
-
- _insert_character(' ');
- }
-
- void _do_argument_completion(char const *str, size_t str_len,
- Command const &command)
- {
- Argument::Name partial_match;
-
- auto argument_fn = [&] (Argument const &arg) {
-
- if (strcmp(arg.name().string(), str, str_len) == 0)
- partial_match = arg.name();
- };
-
- command.for_each_argument(argument_fn);
-
- for (unsigned i = str_len; i < strlen(partial_match.string()); i++)
- _insert_character(partial_match.string()[i]);
-
- _insert_character(' ');
- }
-
- void _complete_argument(char const *str, size_t str_len, Command &command)
- {
- unsigned const matching_parameters =
- _num_partial_matches(str, str_len, command.parameters());
-
- unsigned const matching_arguments =
- _num_matching_arguments(str, str_len, command);
-
- /* matches are ambiguous */
- if (matching_arguments + matching_parameters > 1) {
-
- /*
- * Try to complete additional characters that are common among
- * all matches.
- */
- char buf[Completable::Name::size()];
- strncpy(buf, str, Genode::min(sizeof(buf), str_len + 1));
-
- /* pick any representative as a template to take characters from */
- char const *name = _any_partial_match_name(str, str_len, command.parameters());
- Argument::Name arg_name;
- if (!name) {
- arg_name = _any_matching_argument(str, str_len, command);
- if (strlen(arg_name.string()))
- name = arg_name.string();
- }
-
- size_t i = str_len;
- for (; (i < sizeof(buf) - 1) && (i < strlen(name)); i++) {
-
- buf[i + 0] = name[i];
- buf[i + 1] = 0;
-
- if (matching_parameters !=
- _num_partial_matches(buf, i + 1, command.parameters()))
- break;
-
- if (matching_arguments !=
- _num_matching_arguments(buf, i + 1, command))
- break;
-
- _insert_character(buf[i]);
- }
-
- /*
- * If we managed to do a partial completion, let's yield
- * control to the user.
- */
- if (i > str_len)
- return;
-
- /*
- * No automatic completion was possible, print list of possible
- * parameters and arguments
- */
- size_t const pad =
- max(_width_of_partial_matches(str, str_len, command.parameters()),
- _width_of_matching_arguments(str, str_len, command));
-
- _list_partial_matches(str, str_len, pad, command.parameters());
- _list_matching_arguments(str, str_len, pad, command);
-
- _write_newline();
- _fresh_prompt();
-
- return;
- }
-
- if (matching_parameters == 1)
- _do_completion(str, str_len, command.parameters());
-
- if (matching_arguments == 1)
- _do_argument_completion(str, str_len, command);
- }
-
- void _perform_completion()
- {
- Command *command = _lookup_matching_command();
-
- if (!command) {
- unsigned const matches = _num_partial_matches(_buf, _cursor_pos, _commands);
-
- if (matches == 1)
- _do_completion(_buf, _cursor_pos, _commands);
-
- if (matches > 1) {
- unsigned const pad =
- _width_of_partial_matches(_buf, _cursor_pos, _commands);
- _list_partial_matches(_buf, _cursor_pos, pad, _commands);
- _write_newline();
- _fresh_prompt();
- }
- return;
- }
-
- /*
- * We hava a valid command, now try to complete the parameters...
- */
-
- /* determine token under the cursor */
- Argument_tracker argument_tracker(*command);
-
- Token token(_buf, _buf_size);
- for (; token; token = token.next()) {
-
- argument_tracker.supply_token(token, true);
-
- if (!argument_tracker.valid())
- return;
-
- unsigned long const token_pos = (unsigned long)(token.start() - _buf);
-
- /* we have reached the token under the cursor */
- if (token.type() == Token::IDENT
- && _cursor_pos >= token_pos
- && _cursor_pos <= token_pos + token.len()) {
-
- if (argument_tracker.expect_arg()) {
- char const *start = token.start();
- size_t const len = _cursor_pos - token_pos;
-
- _complete_argument(start, len, *command);
- return;
- }
- }
- }
-
- /* the cursor is positioned at beginning of new argument */
- if (argument_tracker.expect_arg())
- _complete_argument("", 0, *command);
-
- if (argument_tracker.expect_space())
- _insert_character(' ');
- }
-
- public:
-
- /**
- * Constructor
- *
- * \param prompt string to be printed at the beginning of the line
- * \param buf destination buffer
- * \param buf_size destination buffer size
- * \param terminal terminal used as output device
- * \param commands meta information about commands and their arguments
- */
- Line_editor(char const *prompt, char *buf, size_t buf_size,
- Terminal::Session &terminal, Command_registry &commands)
- :
- _prompt(prompt), _prompt_len(strlen(prompt)),
- _buf(buf), _buf_size(buf_size),
- _terminal(terminal), _commands(commands)
- {
- reset();
- }
-
- /**
- * Reset prompt to initial state after construction
- */
- void reset()
- {
- _buf[0] = 0;
- _complete = false;
- _cursor_pos = 0;
- _seq_tracker = Seq_tracker();
- _fresh_prompt();
- }
-
- /**
- * Supply a character of user input
- */
- void submit_input(char c)
- {
- _seq_tracker.input(c);
- _handle_key();
- }
-
- /**
- * Returns true if the editing is complete, i.e., the user pressed the
- * return key.
- */
- bool completed() const { return _complete; }
-};
-
-#endif /* _LINE_EDITOR_H_ */
diff --git a/repos/os/src/app/cli_monitor/main.cc b/repos/os/src/app/cli_monitor/main.cc
deleted file mode 100644
index 6c0a6029e4..0000000000
--- a/repos/os/src/app/cli_monitor/main.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * \brief Simple command-line interface for managing Genode subsystems
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* public CLI-monitor includes */
-#include
-
-/* local includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace Cli_monitor {
-
- struct Main;
- using namespace Genode;
-}
-
-
-/******************
- ** Main program **
- ******************/
-
-struct Cli_monitor::Main
-{
- Genode::Env &_env;
-
- Terminal::Connection _terminal { _env };
-
- Command_registry _commands { };
-
- Child_registry _children { };
-
- Command *_lookup_command(char const *buf)
- {
- Token token(buf);
- for (Command *curr = _commands.first(); curr; curr = curr->next())
- if (strcmp(token.start(), curr->name().string(), token.len()) == 0
- && strlen(curr->name().string()) == token.len())
- return curr;
- return 0;
- }
-
- enum { COMMAND_MAX_LEN = 1000 };
- char _command_buf[COMMAND_MAX_LEN];
- Line_editor _line_editor {
- "genode> ", _command_buf, sizeof(_command_buf), _terminal, _commands };
-
- void _handle_terminal_read_avail();
-
- Signal_handler _terminal_read_avail_handler {
- _env.ep(), *this, &Main::_handle_terminal_read_avail };
-
- /**
- * Handler for child yield responses, or RAM resource-avail signals
- */
- void _handle_yield_response()
- {
- for (Child *child = _children.first(); child; child = child->next())
- child->try_response_to_resource_request();
- }
-
- Signal_handler _yield_response_handler {
- _env.ep(), *this, &Main::_handle_yield_response };
-
- void _handle_child_exit()
- {
- Child *next = nullptr;
- for (Child *child = _children.first(); child; child = next) {
- next = child->next();
- if (child->exited()) {
- _children.remove(child);
- Genode::destroy(_heap, child);
- }
- }
- }
-
- Signal_handler _child_exit_handler {
- _env.ep(), *this, &Main::_handle_child_exit };
-
- void _handle_yield_broadcast()
- {
- /*
- * Compute argument of yield request to be broadcasted to all
- * processes.
- */
- size_t amount = 0;
-
- /* amount needed to reach preservation limit */
- Ram::Status ram_status = _ram.status();
- if (ram_status.avail < ram_status.preserve)
- amount += ram_status.preserve - ram_status.avail;
-
- /* sum of pending resource requests */
- for (Child *child = _children.first(); child; child = child->next())
- amount += child->requested_ram_quota();
-
- for (Child *child = _children.first(); child; child = child->next())
- child->yield(amount, true);
- }
-
- Signal_handler _yield_broadcast_handler {
- _env.ep(), *this, &Main::_handle_yield_broadcast };
-
- Genode::Attached_rom_dataspace _config { _env, "config" };
-
- Xml_node _vfs_config() const
- {
- try { return _config.xml().sub_node("vfs"); }
- catch (Genode::Xml_node::Nonexistent_sub_node) {
- Genode::error("missing '' configuration");
- throw;
- }
- }
-
- size_t _ram_preservation_from_config() const
- {
- if (!_config.xml().has_sub_node("preservation"))
- return 0;
-
- return _config.xml().sub_node("preservation")
- .attribute_value("name", Genode::Number_of_bytes(0));
- }
-
- Ram _ram { _env.pd(), _env.pd_session_cap(), _ram_preservation_from_config(),
- _yield_broadcast_handler, _yield_response_handler };
-
- Heap _heap { _env.ram(), _env.rm() };
-
- Vfs::Simple_env _vfs_env { _env, _heap, _vfs_config() };
-
- Subsystem_config_registry _subsystem_config_registry { _vfs_env.root_dir(), _heap, _env.ep() };
-
- template
- struct Registered : T
- {
- template
- Registered(Command_registry &commands, ARGS &&... args)
- : T(args...) { commands.insert(this); }
- };
-
- /* initialize generic commands */
- Registered _help_command { _commands };
- Registered _kill_command { _commands, _children, _heap };
- Registered _start_command { _commands, _env, _ram, _heap,
- _env.pd(), _env.pd_session_cap(),
- _env.rm(), _children,
- _subsystem_config_registry,
- _yield_response_handler,
- _child_exit_handler };
- Registered _status_command { _commands, _ram, _children };
- Registered _yield_command { _commands, _children };
- Registered _ram_command { _commands, _children, _ram };
-
- Main(Env &env) : _env(env)
- {
- _terminal.read_avail_sigh(_terminal_read_avail_handler);
- }
-};
-
-
-void Cli_monitor::Main::_handle_terminal_read_avail()
-{
- /* supply pending terminal input to line editor */
- while (_terminal.avail() && !_line_editor.completed()) {
- char c = 0;
- _terminal.read(&c, 1);
- _line_editor.submit_input(c);
- }
-
- if (!_line_editor.completed())
- return;
-
- Command *command = _lookup_command(_command_buf);
- if (!command) {
- Token cmd_name(_command_buf);
- tprintf(_terminal, "Error: unknown command \"");
- _terminal.write(cmd_name.start(), cmd_name.len());
- tprintf(_terminal, "\"\n");
- _line_editor.reset();
- return;
- }
-
- /* validate parameters against command meta data */
- Command_line cmd_line(_command_buf, *command);
- Token unexpected = cmd_line.unexpected_parameter();
- if (unexpected) {
- tprintf(_terminal, "Error: unexpected parameter \"");
- _terminal.write(unexpected.start(), unexpected.len());
- tprintf(_terminal, "\"\n");
- _line_editor.reset();
- return;
- }
- command->execute(cmd_line, _terminal);
-
- /*
- * The command might result in a change of the RAM usage. Validate
- * that the preservation is satisfied.
- */
- _ram.validate_preservation();
- _line_editor.reset();
-}
-
-
-void Component::construct(Genode::Env &env) { static Cli_monitor::Main main(env); }
diff --git a/repos/os/src/app/cli_monitor/no_extension.cc b/repos/os/src/app/cli_monitor/no_extension.cc
deleted file mode 100644
index e64df753de..0000000000
--- a/repos/os/src/app/cli_monitor/no_extension.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * \brief Dummy implementation of CLI extension interface
- * \author Norman Feske
- * \date 2013-03-21
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-
-void Cli_monitor::init_extension(Command_registry &) { }
-
diff --git a/repos/os/src/app/cli_monitor/ram_command.h b/repos/os/src/app/cli_monitor/ram_command.h
deleted file mode 100644
index a080db7dfb..0000000000
--- a/repos/os/src/app/cli_monitor/ram_command.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * \brief RAM command
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _RAM_COMMAND_H_
-#define _RAM_COMMAND_H_
-
-/* local includes */
-#include
-
-namespace Cli_monitor { struct Ram_command; }
-
-
-struct Cli_monitor::Ram_command : Command
-{
- Child_registry &_children;
- Ram &_ram;
-
- Parameter _quota_param { "--quota", Parameter::NUMBER, "new RAM quota" };
- Parameter _limit_param { "--limit", Parameter::NUMBER, "on-demand quota limit" };
-
- Ram_command(Child_registry &children, Ram &ram)
- :
- Command("ram", "set RAM quota of subsystem"),
- _children(children), _ram(ram)
- {
- add_parameter(_quota_param);
- add_parameter(_limit_param);
- }
-
- void _set_quota(Terminal::Session &terminal, Child &child, size_t const new_quota)
- {
- size_t const old_quota = child.ram_status().quota;
-
- if (new_quota > old_quota) {
-
- size_t amount = new_quota - old_quota;
- size_t const avail = _ram.avail();
- if (amount > avail) {
- tprintf(terminal, "upgrade of '%s' exceeds available quota of ",
- child.name().string());
- tprint_bytes(terminal, avail);
- tprintf(terminal, "\n");
- amount = avail;
- }
-
- tprintf(terminal, "upgrading quota of '%s' to ", child.name().string());
- tprint_bytes(terminal, old_quota + amount);
- tprintf(terminal, "\n");
-
- try {
- child.upgrade_ram_quota(amount); }
- catch (Ram::Transfer_quota_failed) {
- tprintf(terminal, "Error: transfer_quota failed\n"); }
-
- } if (new_quota < old_quota) {
-
- size_t amount = old_quota - new_quota;
- size_t const avail = child.ram_status().avail;
-
- if (amount > avail) {
- tprintf(terminal, "withdrawal of ");
- tprint_bytes(terminal, amount);
- tprintf(terminal, " exceeds available quota of ");
- tprint_bytes(terminal, avail);
- tprintf(terminal, "\n");
- amount = avail;
- }
-
- tprintf(terminal, "depleting quota of '%s' to ", child.name().string());
- tprint_bytes(terminal, old_quota - amount);
- tprintf(terminal, "\n");
-
- try {
- child.withdraw_ram_quota(amount); }
- catch (Ram::Transfer_quota_failed) {
- tprintf(terminal, "Error: transfer_quota failed\n"); }
- }
- }
-
- void _for_each_argument(Argument_fn const &fn) const override
- {
- auto child_name_fn = [&] (Child_base::Name const &child_name) {
- Argument arg(child_name.string(), "");
- fn(arg);
- };
-
- _children.for_each_child_name(child_name_fn);
- }
-
- void execute(Command_line &cmd, Terminal::Session &terminal) override
- {
- char label[128];
- label[0] = 0;
- if (cmd.argument(0, label, sizeof(label)) == false) {
- tprintf(terminal, "Error: no subsystem name specified\n");
- return;
- }
-
- /* lookup child by its unique name */
- Child *child = _children.first();
- for (; child; child = child->next())
- if (child->name() == label)
- break;
-
- if (!child) {
- tprintf(terminal, "Error: subsystem '%s' does not exist\n", label);
- return;
- }
-
- bool const limit_specified = cmd.parameter_exists("--limit");
- Genode::Number_of_bytes limit = 0;
- if (limit_specified) {
- cmd.parameter("--limit", limit);
- child->ram_limit(limit);
- }
-
- if (cmd.parameter_exists("--quota")) {
- Genode::Number_of_bytes quota = 0;
- cmd.parameter("--quota", quota);
- _set_quota(terminal, *child, quota);
- }
- }
-};
-
-#endif /* _RAM_COMMAND_H_ */
diff --git a/repos/os/src/app/cli_monitor/start_command.h b/repos/os/src/app/cli_monitor/start_command.h
deleted file mode 100644
index e217c59ee5..0000000000
--- a/repos/os/src/app/cli_monitor/start_command.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * \brief Start command
- * \author Norman Feske
- * \date 2013-03-18
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _START_COMMAND_H_
-#define _START_COMMAND_H_
-
-/* Genode includes */
-#include
-
-/* local includes */
-#include
-
-namespace Cli_monitor { class Start_command; }
-
-
-class Cli_monitor::Start_command : public Command
-{
- private:
-
- typedef Genode::Xml_node Xml_node;
- typedef Genode::Signal_context_capability Signal_context_capability;
- typedef Genode::Dataspace_capability Dataspace_capability;
-
- Genode::Env &_env;
- Ram &_ram;
- Genode::Allocator &_alloc;
- Child_registry &_children;
- Genode::Pd_session &_ref_pd;
- Genode::Pd_session_capability _ref_pd_cap;
- Genode::Region_map &_local_rm;
- Subsystem_config_registry &_subsystem_configs;
- List _arguments { };
- Signal_context_capability _yield_response_sigh_cap;
- Signal_context_capability _exit_sig_cap;
-
- void _execute_subsystem(char const *name, Command_line &cmd,
- Terminal::Session &terminal,
- Genode::Xml_node subsystem_node)
- {
- size_t count = 1;
- Genode::Number_of_bytes ram = 0;
- Genode::Number_of_bytes ram_limit = 0;
- size_t caps = subsystem_node.attribute_value("caps", 0UL);
-
- /* read default RAM quota from config */
- try {
- Xml_node rsc = subsystem_node.sub_node("resource");
- for (;; rsc = rsc.next("resource")) {
- if (rsc.attribute("name").has_value("RAM")) {
- rsc.attribute("quantum").value(ram);
-
- if (rsc.has_attribute("limit"))
- rsc.attribute("limit").value(ram_limit);
- break;
- }
- }
- } catch (...) { }
-
- cmd.parameter("--count", count);
- cmd.parameter("--ram", ram);
- cmd.parameter("--ram-limit", ram_limit);
-
- /* acount for cli_monitor local metadata */
- size_t preserve_ram = 100*1024;
- if (count * (ram + preserve_ram) > _ram.avail()) {
- tprintf(terminal, "Error: RAM quota exceeds available quota\n");
- return;
- }
-
- bool const verbose = cmd.parameter_exists("--verbose");
-
- /*
- * Determine binary name
- *
- * Use subsystem name by default, override with '' declaration.
- */
- typedef Genode::String<128> Binary_name;
- Binary_name binary_name;
- try {
- Xml_node bin = subsystem_node.sub_node("binary");
- binary_name = bin.attribute_value("name", Binary_name());
- } catch (...) { }
-
- for (unsigned i = 0; i < count; i++) {
-
- /* generate unique child name */
- char label[Child_registry::CHILD_NAME_MAX_LEN];
- _children.unique_child_name(name, label, sizeof(label));
-
- tprintf(terminal, "starting new subsystem '%s'\n", label);
-
- if (verbose) {
- tprintf(terminal, " RAM quota: ");
- tprint_bytes(terminal, ram);
- tprintf(terminal,"\n");
- if (ram_limit) {
- tprintf(terminal, " RAM limit: ");
- tprint_bytes(terminal, ram_limit);
- tprintf(terminal,"\n");
- }
- tprintf(terminal, " binary: %s\n", binary_name.string());
- }
-
- Child *child = 0;
- try {
- child = new (_alloc)
- Child(_env, _ram, _alloc, label, binary_name,
- _ref_pd, _ref_pd_cap, _local_rm,
- Genode::Cap_quota{caps}, ram, ram_limit,
- _yield_response_sigh_cap, _exit_sig_cap);
- }
- catch (Genode::Service_denied) {
- tprintf(terminal, "Error: could not start child \"%s\"\n",
- binary_name);
- return;
- }
- catch (Child::Quota_exceeded) {
- tprintf(terminal, "Error: insufficient memory, need ");
- tprint_bytes(terminal, ram + Child::DONATED_RAM_QUOTA);
- tprintf(terminal, ", have ");
- tprint_bytes(terminal, _ram.avail());
- tprintf(terminal, "\n");
- return;
- }
- catch (Genode::Allocator::Out_of_memory) {
- tprintf(terminal, "Error: could not allocate meta data, out of memory\n");
- return;
- }
-
- /* configure child */
- try {
- Xml_node config_node = subsystem_node.sub_node("config");
- config_node.with_raw_node([&] (char const *start, size_t length) {
- child->configure(start, length); });
-
- if (verbose)
- tprintf(terminal, " config: inline\n");
- } catch (...) {
- if (verbose)
- tprintf(terminal, " config: none\n");
- }
-
- _children.insert(child);
- child->start();
- }
- }
-
- Parameter _count_param { "--count", Parameter::NUMBER, "number of instances" };
- Parameter _ram_param { "--ram", Parameter::NUMBER, "initial RAM quota" };
- Parameter _ram_limit_param { "--ram-limit", Parameter::NUMBER, "limit for expanding RAM quota" };
- Parameter _verbose_param { "--verbose", Parameter::VOID, "show diagnostics" };
-
- public:
-
- Start_command(Genode::Env &env,
- Ram &ram,
- Genode::Allocator &alloc,
- Genode::Pd_session &ref_pd,
- Genode::Pd_session_capability ref_pd_cap,
- Genode::Region_map &local_rm,
- Child_registry &children,
- Subsystem_config_registry &subsustem_configs,
- Signal_context_capability yield_response_sigh_cap,
- Signal_context_capability exit_sig_cap)
- :
- Command("start", "create new subsystem"),
- _env(env), _ram(ram), _alloc(alloc), _children(children),
- _ref_pd(ref_pd), _ref_pd_cap(ref_pd_cap), _local_rm(local_rm),
- _subsystem_configs(subsustem_configs),
- _yield_response_sigh_cap(yield_response_sigh_cap),
- _exit_sig_cap(exit_sig_cap)
- {
- add_parameter(_count_param);
- add_parameter(_ram_param);
- add_parameter(_ram_limit_param);
- add_parameter(_verbose_param);
- }
-
- void _for_each_argument(Argument_fn const &fn) const override
- {
- /* functor for processing a subsystem configuration */
- auto process_subsystem_config_fn = [&] (Genode::Xml_node node) {
-
- if (!node.has_attribute("name")) {
- Genode::warning("Missing name in '' configuration");
- return;
- }
-
- typedef Genode::String<64> Name;
- Name const name = node.attribute_value("name", Name());
-
- char const *prefix = "config: ";
- size_t const prefix_len = strlen(prefix);
-
- char help[Parameter::Short_help::size() + prefix_len];
- strncpy(help, prefix, ~0);
- try {
- Genode::Xml_attribute const help_attr = node.attribute("help");
- help_attr.with_raw_value([&] (char const *start, size_t len) {
- strncpy(help + prefix_len, start,
- Genode::min(len, Parameter::Short_help::size())); });
- }
- catch (Xml_node::Nonexistent_attribute) {
- Genode::warning("Missing help in '' configuration");
- return;
- }
-
- Argument arg(name.string(), help);
- fn(arg);
- };
-
- /* scan subsystem config registry for possible subsystem arguments */
- _subsystem_configs.for_each_config(process_subsystem_config_fn);
- }
-
- void execute(Command_line &cmd, Terminal::Session &terminal) override
- {
- char name[128];
- name[0] = 0;
- if (cmd.argument(0, name, sizeof(name)) == false) {
- tprintf(terminal, "Error: no configuration name specified\n");
- return;
- }
-
- char buf[128];
- if (cmd.argument(1, buf, sizeof(buf))) {
- tprintf(terminal, "Error: unexpected argument \"%s\"\n", buf);
- return;
- }
-
- try {
- _subsystem_configs.for_config(name, [&] (Genode::Xml_node node)
- {
- _execute_subsystem(name, cmd, terminal, node);
- });
-
- } catch (Subsystem_config_registry::Nonexistent_subsystem_config) {
- tprintf(terminal, "Error: no configuration for \"%s\"\n", name);
- }
- }
-
- List &arguments() { return _arguments; }
-};
-
-#endif /* _START_COMMAND_H_ */
diff --git a/repos/os/src/app/cli_monitor/status_command.h b/repos/os/src/app/cli_monitor/status_command.h
deleted file mode 100644
index 929a56d6f5..0000000000
--- a/repos/os/src/app/cli_monitor/status_command.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * \brief Status command
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _STATUS_COMMAND_H_
-#define _STATUS_COMMAND_H_
-
-/* local includes */
-#include
-#include
-
-namespace Cli_monitor { struct Status_command; }
-
-
-struct Cli_monitor::Status_command : Command
-{
- Child_registry &_children;
- Ram &_ram;
-
- Status_command(Ram &ram, Child_registry &children)
- :
- Command("status", "show runtime status"),
- _children(children), _ram(ram)
- { }
-
- void execute(Command_line &, Terminal::Session &terminal) override
- {
- using Terminal::tprintf;
-
- Ram::Status const ram_status = _ram.status();
-
- tprint_status_bytes(terminal, " RAM quota: ", ram_status.quota);
- tprint_status_bytes(terminal, " used: ", ram_status.used);
- tprint_status_bytes(terminal, " avail: ", ram_status.avail);
- tprint_status_bytes(terminal, " preserve: ", ram_status.preserve);
-
- tprintf(terminal, "\n");
-
- struct Child_info
- {
- enum Column { NAME, QUOTA, LIMIT, XFER, USED, AVAIL, STATUS };
-
- constexpr static size_t num_columns() { return STATUS + 1; }
-
- char const *name = 0;
- Child::Ram_status ram_status { };
-
- static char const *label(Column column)
- {
- switch (column) {
- case NAME: return "process";
- case QUOTA: return "quota";
- case LIMIT: return "limit";
- case XFER: return "xfer";
- case USED: return "alloc";
- case AVAIL: return "avail";
- case STATUS: return "status";
- };
- return "";
- }
-
- size_t len(Column column) const
- {
- switch (column) {
- case NAME: return strlen(name);
- case QUOTA: return format_mib(ram_status.quota);
- case LIMIT:
- return ram_status.limit ? format_mib(ram_status.limit) : 0;
-
- case XFER: return format_mib(ram_status.xfer);
- case USED: return format_mib(ram_status.used);
- case AVAIL: return format_mib(ram_status.avail);
- case STATUS:
- {
- size_t const req = ram_status.req;
- return req ? strlen("req ") + format_mib(req) : 0;
- }
- };
- return 0;
- }
-
- static bool left_aligned(Column column)
- {
- switch (column) {
- case NAME: return true;
- case QUOTA: return false;
- case LIMIT: return false;
- case XFER: return false;
- case USED: return false;
- case AVAIL: return false;
- case STATUS: return true;
- };
- return false;
- }
-
- void print_cell(Terminal::Session &terminal, Column column)
- {
- switch (column) {
- case NAME: tprintf(terminal, "%s", name); break;
- case QUOTA: tprint_mib(terminal, ram_status.quota); break;
- case LIMIT:
-
- if (ram_status.limit)
- tprint_mib(terminal, ram_status.limit);
- break;
-
- case XFER: tprint_mib(terminal, ram_status.xfer); break;
- case USED: tprint_mib(terminal, ram_status.used); break;
- case AVAIL: tprint_mib(terminal, ram_status.avail); break;
- case STATUS:
- if (ram_status.req) {
- tprintf(terminal, "req ");
- tprint_mib(terminal, ram_status.req);
- }
- break;
- };
- }
-
- Child_info() { }
- Child_info(char const *name, Child::Ram_status ram_status)
- :
- name(name), ram_status(ram_status)
- { }
- };
-
- /*
- * Take snapshot of child information.
- */
- size_t num_children = 0;
- for (Child *c = _children.first(); c; c = c->next())
- num_children++;
-
- Child_info child_info[num_children];
- unsigned i = 0;
- for (Child *c = _children.first(); c && i < num_children; c = c->next(), i++)
- child_info[i] = Child_info(c->name().string(), c->ram_status());
-
- /*
- * Print table
- */
- if (num_children) {
- Table::print(terminal, child_info, num_children);
- tprintf(terminal, "\n");
- }
- }
-};
-
-#endif /* _STATUS_COMMAND_H_ */
diff --git a/repos/os/src/app/cli_monitor/subsystem_config_registry.h b/repos/os/src/app/cli_monitor/subsystem_config_registry.h
deleted file mode 100644
index 3477b8ea6d..0000000000
--- a/repos/os/src/app/cli_monitor/subsystem_config_registry.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * \brief Registry of subsystem configuration
- * \author Norman Feske
- * \date 2015-01-27
- */
-
-/*
- * Copyright (C) 2015-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _SUBSYSTEM_CONFIG_REGISTRY_H_
-#define _SUBSYSTEM_CONFIG_REGISTRY_H_
-
-/* Genode includes */
-#include
-#include
-
-namespace Cli_monitor { class Subsystem_config_registry; }
-
-
-class Cli_monitor::Subsystem_config_registry
-{
- public:
-
- /**
- * Exception type
- */
- class Nonexistent_subsystem_config { };
-
- private:
-
- Vfs::File_system &_fs;
- Genode::Allocator &_alloc;
- Genode::Entrypoint &_ep;
-
- enum { CONFIG_BUF_SIZE = 32*1024 };
- char _config_buf[CONFIG_BUF_SIZE];
-
- char const *_subsystems_path() { return "/subsystems"; }
- char const *_subsystem_suffix() { return ".subsystem"; }
-
- /**
- * Return index of ".subsystem" suffix in dirent name
- *
- * \return index, or 0 if no matching suffix could be found
- */
- unsigned _subsystem_suffix(Vfs::Directory_service::Dirent const &dirent)
- {
- unsigned found = 0;
- for (unsigned i = 0; i < sizeof(dirent.name.buf) && dirent.name.buf[i]; i++)
- if (Genode::strcmp(_subsystem_suffix(), &dirent.name.buf[i]) == 0)
- found = i;
-
- return found;
- }
-
-
- public:
-
- /**
- * Constructor
- */
- Subsystem_config_registry(Vfs::File_system &fs, Genode::Allocator &alloc,
- Genode::Entrypoint &ep)
- :
- _fs(fs), _alloc(alloc), _ep(ep)
- { }
-
- /**
- * Execute functor 'fn' for specified subsystem name
- *
- * The functor is called with the subsystem XML node as argument
- *
- * \throw Nonexistent_subsystem_config
- */
- template
- void for_config(char const *name, FN const &fn)
- {
- using Genode::error;
-
- /*
- * Load subsystem configuration
- */
-
- Genode::Path<256> path(_subsystems_path());
- path.append("/");
- path.append(name);
- path.append(_subsystem_suffix());
-
- Vfs::Vfs_handle *handle = nullptr;
-
- Vfs::Directory_service::Open_result const open_result =
- _fs.open(path.base(),
- Vfs::Directory_service::OPEN_MODE_RDONLY,
- &handle, _alloc);
-
- Vfs::Vfs_handle::Guard handle_guard(handle);
-
- if (open_result != Vfs::Directory_service::OPEN_OK) {
- error("could not open '", path, "', err=", (int)open_result);
- throw Nonexistent_subsystem_config();
- }
-
- Vfs::file_size out_count = 0;
-
- handle->fs().queue_read(handle, sizeof(_config_buf));
-
- Vfs::File_io_service::Read_result read_result;
-
- while ((read_result =
- handle->fs().complete_read(handle, _config_buf,
- sizeof(_config_buf),
- out_count)) ==
- Vfs::File_io_service::READ_QUEUED)
- _ep.wait_and_dispatch_one_io_signal();
-
- if (read_result != Vfs::File_io_service::READ_OK) {
- error("could not read '", path, "', err=", (int)read_result);
- throw Nonexistent_subsystem_config();
- }
-
- try {
- Genode::Xml_node subsystem_node(_config_buf, out_count);
- fn(subsystem_node);
-
- } catch (Genode::Xml_node::Invalid_syntax) {
- error("subsystem configuration has invalid syntax");
- throw Nonexistent_subsystem_config();
-
- } catch (Genode::Xml_node::Nonexistent_sub_node) {
- error("invalid subsystem configuration");
- throw Nonexistent_subsystem_config();
- }
- }
-
- /**
- * Call specified functor for each subsystem config
- */
- template
- void for_each_config(FN const &fn)
- {
- using Genode::error;
-
- Vfs::Vfs_handle *dir_handle;
-
- if (_fs.opendir(_subsystems_path(), false, &dir_handle, _alloc) !=
- Vfs::Directory_service::OPENDIR_OK) {
- error("could not access directory '", _subsystems_path(), "'");
- return;
- }
-
- /* iterate over the directory entries */
- for (unsigned i = 0;; i++) {
-
- Vfs::Directory_service::Dirent dirent { };
-
- dir_handle->seek(i * sizeof(dirent));
- dir_handle->fs().queue_read(dir_handle, sizeof(dirent));
-
- Vfs::file_size out_count;
- while (dir_handle->fs().complete_read(dir_handle,
- (char*)&dirent,
- sizeof(dirent),
- out_count) ==
- Vfs::File_io_service::READ_QUEUED)
- _ep.wait_and_dispatch_one_io_signal();
-
- if (dirent.type == Vfs::Directory_service::Dirent_type::END) {
- _fs.close(dir_handle);
- return;
- }
-
- unsigned const subsystem_suffix = _subsystem_suffix(dirent);
-
- /* if file has a matching suffix, apply 'fn' */
- if (subsystem_suffix) {
-
- /* subsystem name is file name without the suffix */
- char name[sizeof(dirent.name.buf)];
- Genode::strncpy(name, dirent.name.buf, subsystem_suffix + 1);
-
- try {
- for_config(name, fn);
- } catch (Nonexistent_subsystem_config) { }
- }
- }
-
- _fs.close(dir_handle);
- }
-};
-
-#endif /* _PROCESS_ARG_REGISTRY_H_ */
diff --git a/repos/os/src/app/cli_monitor/table.h b/repos/os/src/app/cli_monitor/table.h
deleted file mode 100644
index 2ba99495f9..0000000000
--- a/repos/os/src/app/cli_monitor/table.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * \brief Utility for printing a table to the terminal
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TABLE_H_
-#define _TABLE_H_
-
-#include
-
-namespace Cli_monitor { template class Table; }
-
-
-template
-class Cli_monitor::Table
-{
- private:
-
- static void _print_cell(TI &info, Terminal::Session &terminal,
- typename TI::Column column, size_t column_size)
- {
- size_t const padding = column_size - info.len(column);
-
- if (!TI::left_aligned(column))
- tprint_padding(terminal, padding);
-
- info.print_cell(terminal, column);
-
- if (TI::left_aligned(column))
- tprint_padding(terminal, padding);
- }
-
- /**
- * Print centered title of table column
- */
- static void _print_label(Terminal::Session &terminal,
- typename TI::Column column, size_t column_size)
- {
- size_t const padding = column_size - strlen(TI::label(column));
- size_t const left_padding = padding / 2;
-
- tprint_padding(terminal, left_padding);
- tprintf(terminal, "%s", TI::label(column));
- tprint_padding(terminal, padding - left_padding);
- }
-
- public:
-
- static void print(Terminal::Session &terminal, TI info[], unsigned num_rows)
- {
- /*
- * Determine formatting of table
- */
- size_t column_size[TI::num_columns()];
- for (unsigned i = 0; i < TI::num_columns(); i++)
- column_size[i] = strlen(TI::label((typename TI::Column)i));
-
- for (unsigned i = 0; i < num_rows; i++) {
- for (unsigned j = 0; j < TI::num_columns(); j++)
- column_size[j] = max(column_size[j],
- info[i].len((typename TI::Column)j));
- }
-
- /*
- * Print table
- */
- tprintf(terminal, " ");
- for (unsigned j = 0; j < TI::num_columns(); j++) {
- _print_label(terminal, (typename TI::Column)j, column_size[j]);
- if (j < TI::num_columns() - 1) tprintf(terminal, " | ");
- }
- tprintf(terminal, "\n");
-
- tprintf(terminal, " ");
- for (unsigned j = 0; j < TI::num_columns(); j++) {
- for (unsigned i = 0; i < column_size[j]; i++)
- tprintf(terminal, "-");
- if (j < TI::num_columns() - 1) tprintf(terminal, "-+-");
- }
- tprintf(terminal, "\n");
-
- for (unsigned i = 0; i < num_rows; i++) {
- tprintf(terminal, " ");
- for (unsigned j = 0; j < TI::num_columns(); j++) {
- _print_cell(info[i], terminal, (typename TI::Column)j, column_size[j]);
- if (j < TI::num_columns() - 1) tprintf(terminal, " | ");
- }
- tprintf(terminal, "\n");
- }
- }
-};
-
-#endif /* _TABLE_H_ */
diff --git a/repos/os/src/app/cli_monitor/target.mk b/repos/os/src/app/cli_monitor/target.mk
deleted file mode 100644
index 41ee20a17e..0000000000
--- a/repos/os/src/app/cli_monitor/target.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET = cli_monitor
-SRC_CC = main.cc
-LIBS = base vfs
-INC_DIR += $(PRG_DIR)
diff --git a/repos/os/src/app/cli_monitor/terminal_util.h b/repos/os/src/app/cli_monitor/terminal_util.h
deleted file mode 100644
index 75413a1447..0000000000
--- a/repos/os/src/app/cli_monitor/terminal_util.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * \brief Convenience functions for operating on a terminal session
- * \author Norman Feske
- * \date 2013-03-19
- */
-
-#ifndef _TERMINAL_UTIL_H_
-#define _TERMINAL_UTIL_H_
-
-/* Genode includes */
-#include
-#include
-
-namespace Terminal {
-
- static inline void tprintf(Session &terminal, const char *format_args, ...)
- {
- using namespace Genode;
-
- enum { MAX_LEN = 256 };
- char buf[MAX_LEN];
-
- /* process format string */
- va_list list;
- va_start(list, format_args);
-
- String_console sc(buf, MAX_LEN);
- sc.vprintf(format_args, list);
-
- va_end(list);
-
- terminal.write(buf, strlen(buf));
- }
-}
-
-#endif /* _TERMINAL_UTIL_H_ */
diff --git a/repos/os/src/app/cli_monitor/yield_command.h b/repos/os/src/app/cli_monitor/yield_command.h
deleted file mode 100644
index bc0e2ebdf9..0000000000
--- a/repos/os/src/app/cli_monitor/yield_command.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * \brief Yield command
- * \author Norman Feske
- * \date 2013-10-05
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _YIELD_COMMAND_H_
-#define _YIELD_COMMAND_H_
-
-/* local includes */
-#include
-
-namespace Cli_monitor { struct Yield_command; }
-
-
-struct Cli_monitor::Yield_command : Command
-{
- Child_registry &_children;
-
- Parameter _ram_param { "--ram", Parameter::NUMBER, "RAM quota to free" };
- Parameter _greedy_param { "--greedy", Parameter::VOID, "withdraw yielded RAM quota" };
-
- Yield_command(Child_registry &children)
- :
- Command("yield", "instruct subsystem to yield resources"),
- _children(children)
- {
- add_parameter(_ram_param);
- add_parameter(_greedy_param);
- }
-
- void _for_each_argument(Argument_fn const &fn) const override
- {
- auto child_name_fn = [&] (Child_base::Name const &child_name) {
- Argument arg(child_name.string(), "");
- fn(arg);
- };
-
- _children.for_each_child_name(child_name_fn);
- }
-
- void execute(Command_line &cmd, Terminal::Session &terminal) override
- {
- char label[128];
- label[0] = 0;
- if (cmd.argument(0, label, sizeof(label)) == false) {
- tprintf(terminal, "Error: no subsystem name specified\n");
- return;
- }
-
- Genode::Number_of_bytes ram = 0;
- cmd.parameter("--ram", ram);
-
- bool const greedy = cmd.parameter_exists("--greedy");
-
- /* lookup child by its unique name */
- Child *child = _children.first();
- for (; child; child = child->next())
- if (child->name() == label)
- break;
-
- if (!child) {
- tprintf(terminal, "Error: subsystem '%s' does not exist\n", label);
- return;
- }
-
- child->yield(ram, greedy);
-
- tprintf(terminal, "requesting '%s' to yield ", child->name().string());
- tprint_bytes(terminal, ram);
- tprintf(terminal, "\n");
- }
-};
-
-#endif /* _YIELD_COMMAND_H_ */
diff --git a/repos/os/src/server/fs_log/README b/repos/os/src/server/fs_log/README
index db41b850b1..0c35d004da 100644
--- a/repos/os/src/server/fs_log/README
+++ b/repos/os/src/server/fs_log/README
@@ -18,7 +18,7 @@ the file "/log".
!
!
!
-!
+!
!
!
!