libc: don't copy Xml_node

This patch reworks the libc's internal config handling by replacing
scattered Xml_node accesses by the new 'Config' type that is parsed
at once. The config ROM has been moved from 'Env_implementation' to
the libc kernel.

Issue #5411
This commit is contained in:
Norman Feske 2025-03-25 19:08:00 +01:00
parent 636eb7b53f
commit 368509ff9b
20 changed files with 378 additions and 392 deletions

View File

@ -33,7 +33,7 @@ static void populate_args_and_env(Libc::Env &env, int &argc, char **&argv, char
attr.with_raw_value(fn); });
};
env.config([&] (Xml_node const &node) {
env.with_config([&] (Xml_node const &node) {
int envc = 0;
@ -84,7 +84,7 @@ static void populate_args_and_env(Libc::Env &env, int &argc, char **&argv, char
/* insert an environment variable */
if (node.has_type("env")) try {
auto check_attr = [] (Xml_node node, auto key) {
auto check_attr = [] (Xml_node const &node, auto key) {
if (!node.has_attribute(key))
Genode::warning("<env> node lacks '", key, "' attribute"); };

View File

@ -22,41 +22,43 @@
#define _INCLUDE__LIBC__COMPONENT_H_
#include <util/meta.h>
#include <util/callable.h>
#include <base/env.h>
#include <base/stdint.h>
#include <util/xml_node.h>
namespace Libc { class Config_accessor; }
struct Libc::Config_accessor : Genode::Interface, Genode::Noncopyable
{
using With_config = Genode::Callable<void, Genode::Xml_node const &>;
virtual void _with_config(With_config::Ft const &) const = 0;
/**
* Call 'fn' with the 'Xml_node const &' of the component configuration
*/
void with_config(auto const &fn) const
{
_with_config( With_config::Fn { fn } );
}
};
namespace Libc { class Env; }
namespace Vfs { struct Env; }
/**
* Interface to be provided by the component implementation
*/
class Libc::Env : public Genode::Env
struct Libc::Env : Genode::Env, Config_accessor
{
private:
virtual Genode::Xml_node _config_xml() const = 0;
public:
/**
* Component configuration
*/
template <typename FUNC>
void config(FUNC const &func) const {
func(_config_xml()); }
/**
* Virtual file system configured for this component
*/
virtual Vfs::Env &vfs_env() = 0;
/**
* Libc configuration for this component
*/
virtual Genode::Xml_node libc_config() = 0;
/**
* Virtual file system configured for this component
*/
virtual Vfs::Env &vfs_env() = 0;
};

View File

@ -45,8 +45,6 @@ void Component::construct(Genode::Env &env)
static long _kernel_obj[(sizeof(Libc::Kernel) + sizeof(long))/sizeof(long)];
Libc::Kernel &kernel = *new (_kernel_obj) Libc::Kernel(env, heap);
Libc::libc_config_init(kernel.libc_env().libc_config());
/*
* XXX The following two steps leave us with the dilemma that we don't know
* which linked library may depend on the successfull initialization of a

View File

@ -314,7 +314,7 @@ static Libc::Binary_name *_binary_name_ptr;
static Libc::File_descriptor_allocator *_fd_alloc_ptr;
void Libc::init_execve(Env &env, Genode::Allocator &alloc, void *user_stack_ptr,
void Libc::init_execve(Genode::Env &env, Genode::Allocator &alloc, void *user_stack_ptr,
Reset_malloc_heap &reset_malloc_heap, Binary_name &binary_name,
File_descriptor_allocator &fd_alloc)
{

View File

@ -74,10 +74,12 @@ void Libc::init_file_operations(Cwd &cwd, File_descriptor_allocator &fd_alloc,
_fd_alloc_ptr = &fd_alloc;
_cwd_ptr = &cwd;
config_accessor.config().with_optional_sub_node("libc", [&] (Xml_node libc) {
libc.with_optional_sub_node("mmap", [&] (Xml_node mmap) {
_mmap_align_log2 = mmap.attribute_value("align_log2",
(unsigned int)PAGE_SHIFT);
config_accessor.with_config([&] (Xml_node const &config) {
config.with_optional_sub_node("libc", [&] (Xml_node libc) {
libc.with_optional_sub_node("mmap", [&] (Xml_node mmap) {
_mmap_align_log2 = mmap.attribute_value("align_log2",
(unsigned int)PAGE_SHIFT);
});
});
});
}

View File

@ -60,7 +60,7 @@ namespace { using Fn = Monitor::Function_result; }
static pid_t fork_result;
static Env *_env_ptr;
static Genode::Env *_env_ptr;
static File_descriptor_allocator *_fd_alloc_ptr;
static Allocator *_alloc_ptr;
static Monitor *_monitor_ptr;
@ -88,34 +88,35 @@ struct Libc::Child_config
{
Constructible<Attached_ram_dataspace> _ds { };
Env &_env;
Genode::Env &_env;
pid_t const _pid;
void _generate(Xml_generator &xml, Xml_node const &config,
File_descriptor_allocator &);
Child_config(Env &env, Config_accessor const &config_accessor,
Child_config(Genode::Env &env, Config_accessor const &config_accessor,
File_descriptor_allocator &fd_alloc, pid_t pid)
:
_env(env), _pid(pid)
{
Xml_node const config = config_accessor.config();
config_accessor.with_config([&] (Xml_node const &config) {
size_t buffer_size = 4096;
size_t buffer_size = 4096;
retry<Xml_generator::Buffer_exceeded>(
retry<Xml_generator::Buffer_exceeded>(
[&] () {
_ds.construct(env.ram(), env.rm(), buffer_size);
[&] {
_ds.construct(env.ram(), env.rm(), buffer_size);
Xml_generator
xml(_ds->local_addr<char>(), buffer_size, "config", [&] () {
_generate(xml, config, fd_alloc); });
},
Xml_generator
xml(_ds->local_addr<char>(), buffer_size, "config", [&] {
_generate(xml, config, fd_alloc); });
},
[&] () { buffer_size += 4096; }
);
[&] { buffer_size += 4096; }
);
});
}
Rom_dataspace_capability ds_cap() const
@ -201,8 +202,8 @@ class Libc::Parent_services : Noncopyable
{
private:
Env &_env;
Allocator &_alloc;
Genode::Env &_env;
Allocator &_alloc;
using Registered_service = Registered<Parent_service>;
@ -210,7 +211,8 @@ class Libc::Parent_services : Noncopyable
public:
Parent_services(Env &env, Allocator &alloc) : _env(env), _alloc(alloc) { }
Parent_services(Genode::Env &env, Allocator &alloc)
: _env(env), _alloc(alloc) { }
~Parent_services()
{
@ -290,7 +292,7 @@ struct Libc::Local_rom_services : Noncopyable
Registry<Registered_service> _services { };
Local_rom_services(Env &env, Entrypoint &fork_ep, Allocator &alloc)
Local_rom_services(Genode::Env &env, Entrypoint &fork_ep, Allocator &alloc)
:
_alloc(alloc)
{
@ -340,7 +342,7 @@ struct Libc::Local_clone_service : Noncopyable
.cap_quota = { Clone_session::CAP_QUOTA } };
}
Session(Env &env, Entrypoint &ep)
Session(Genode::Env &env, Entrypoint &ep)
:
Session_object<Clone_session, Session>(ep.rpc_ep(), _resources(),
"cloned", Session::Diag()),
@ -387,7 +389,7 @@ struct Libc::Local_clone_service : Noncopyable
Service service { _factory };
Local_clone_service(Env &env, Entrypoint &ep, Child_ready &child_ready)
Local_clone_service(Genode::Env &env, Entrypoint &ep, Child_ready &child_ready)
:
_session(env, ep), _child_ready(child_ready),
_child_ready_handler(env.ep(), *this, &Local_clone_service::_handle_child_ready),
@ -398,7 +400,7 @@ struct Libc::Local_clone_service : Noncopyable
struct Libc::Forked_child : Child_policy, Child_ready
{
Env &_env;
Genode::Env &_env;
Binary_name const _binary_name;
@ -551,7 +553,7 @@ struct Libc::Forked_child : Child_policy, Child_ready
Child _child;
Forked_child(Env &env,
Forked_child(Genode::Env &env,
File_descriptor_allocator &fd_alloc,
Entrypoint &fork_ep,
Allocator &alloc,
@ -585,7 +587,7 @@ static Forked_child * fork_kernel_routine()
abort();
}
Env &env = *_env_ptr;
Genode::Env &env = *_env_ptr;
Allocator &alloc = *_alloc_ptr;
Libc::Signal &signal = *_signal_ptr;
@ -752,7 +754,7 @@ extern "C" pid_t __sys_wait4(pid_t pid, int *status, int options, rusage *rusage
extern "C" pid_t wait4(pid_t, int *, int, rusage *) __attribute__((weak, alias("__sys_wait4")));
void Libc::init_fork(Env &env, File_descriptor_allocator &fd_alloc,
void Libc::init_fork(Genode::Env &env, File_descriptor_allocator &fd_alloc,
Config_accessor const &config_accessor,
Allocator &alloc, Heap &malloc_heap, pid_t pid,
Monitor &monitor, Signal &signal,

View File

@ -86,7 +86,7 @@ static passwd passwd_from_fields(Passwd_fields &fields)
}
void Libc::init_passwd(Xml_node config)
void Libc::init_passwd(Xml_node const &config)
{
static Passwd_fields fields {
.name = config.attribute_value("name", Passwd_string("root")),

View File

@ -23,18 +23,30 @@ extern "C" {
/* libc-internal includes */
#include <internal/errno.h>
#include <internal/types.h>
#include <internal/init.h>
/* Genode includes */
#include <trace/timestamp.h>
#include <base/log.h>
#include <util/string.h>
namespace Libc { extern char const *config_rng(); }
using namespace Libc;
static Config const *_config_ptr;
void Libc::init_random(Config const &config)
{
_config_ptr = &config;
}
static ssize_t read_rng(char *buf, size_t buflen)
{
struct Missing_call_of_init_random : Genode::Exception { };
if (!_config_ptr)
throw Missing_call_of_init_random();
static int rng_fd { -1 };
static bool fallback { false };
@ -51,7 +63,7 @@ static ssize_t read_rng(char *buf, size_t buflen)
}
if (rng_fd == -1) {
if (!::strcmp(config_rng(), "")) {
if (_config_ptr->rng.length() <= 1) {
warning("Libc RNG not configured");
/* initialize the FreeBSD random facility */
@ -61,9 +73,9 @@ static ssize_t read_rng(char *buf, size_t buflen)
return read_rng(buf, buflen);
}
rng_fd = open(config_rng(), O_RDONLY);
rng_fd = open(_config_ptr->rng.string(), O_RDONLY);
if (rng_fd == -1) {
error("RNG device ", Cstring(config_rng()), " not readable!");
error("RNG device ", _config_ptr->rng.string(), " not readable!");
exit(~0);
}
}

View File

@ -0,0 +1,94 @@
/*
* \brief Libc config
* \author Norman Feske
* \date 2025-03-26
*/
/*
* Copyright (C) 2025 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 _LIBC__INTERNAL__CONFIG_H_
#define _LIBC__INTERNAL__CONFIG_H_
/* Genode includes */
#include <util/xml_node.h>
#include <base/component.h>
/* libc includes */
#include <unistd.h>
#include <internal/types.h>
namespace Libc { class Config; }
struct Libc::Config
{
using Path = String<Vfs::MAX_PATH_LEN>;
bool update_mtime, cloned;
pid_t pid;
Path rtc, rng, pipe, socket, nameserver;
size_t stack_size;
static Config _from_libc_xml(Xml_node const &libc)
{
Path const socket = libc.attribute_value("socket", Path());
Path const default_nameserver { socket, "/nameserver" };
size_t stack_size = Component::stack_size();
libc.with_optional_sub_node("stack", [&] (Xml_node stack) {
stack_size = stack.attribute_value("size", Number_of_bytes(0)); });
return {
.update_mtime = libc.attribute_value("update_mtime", true),
.cloned = libc.attribute_value("cloned", false),
.pid = libc.attribute_value("pid", pid_t(0)),
.rtc = libc.attribute_value("rtc", Path()),
.rng = libc.attribute_value("rng", Path()),
.pipe = libc.attribute_value("pipe", Path()),
.socket = socket,
.nameserver = libc.attribute_value("nameserver_file",
default_nameserver),
.stack_size = stack_size,
};
}
static Config from_xml(Xml_node const &config)
{
Config result { };
config.with_optional_sub_node("libc", [&] (Xml_node const &libc) {
result = _from_libc_xml(libc); });
return result;
}
};
namespace Libc {
static inline void with_vfs_config(Xml_node const &config, auto const &fn)
{
static Xml_node const empty_vfs { "<vfs/>" };
config.with_sub_node("vfs",
[&] (Xml_node const &vfs_config) { fn(vfs_config); },
[&] {
config.with_sub_node("libc",
[&] (Xml_node const &libc) {
libc.with_sub_node("vfs",
[&] (Xml_node const &vfs_config) {
warning("'<config> <libc> <vfs/>' is deprecated, "
"please move to '<config> <vfs/>'");
fn(vfs_config);
},
[&] { fn(empty_vfs); });
},
[&] { fn(empty_vfs); });
});
}
}
#endif /* _LIBC__INTERNAL__CONFIG_H_ */

View File

@ -26,48 +26,22 @@
namespace Libc { class Env_implementation; }
class Libc::Env_implementation : public Libc::Env, public Config_accessor
class Libc::Env_implementation : public Libc::Env
{
private:
Genode::Env &_env;
Attached_rom_dataspace _config { _env, "config" };
Vfs::Env &_vfs_env;
Xml_node _vfs_config()
{
try { return _config.xml().sub_node("vfs"); }
catch (Xml_node::Nonexistent_sub_node) { }
try {
Xml_node node = _config.xml().sub_node("libc").sub_node("vfs");
warning("'<config> <libc> <vfs/>' is deprecated, "
"please move to '<config> <vfs/>'");
return node;
}
catch (Xml_node::Nonexistent_sub_node) { }
return Xml_node("<vfs/>");
}
Xml_node _libc_config()
{
try { return _config.xml().sub_node("libc"); }
catch (Xml_node::Nonexistent_sub_node) { }
return Xml_node("<libc/>");
}
Vfs::Simple_env _vfs_env;
Xml_node _config_xml() const override {
return _config.xml(); };
Attached_rom_dataspace const &_config_rom;
public:
Env_implementation(Genode::Env &env, Genode::Allocator &alloc,
Vfs::Env::User &vfs_user)
Env_implementation(Genode::Env &env, Vfs::Env &vfs_env,
Attached_rom_dataspace const &config_rom)
:
_env(env), _vfs_env(_env, alloc, _vfs_config(), vfs_user)
_env(env), _vfs_env(vfs_env), _config_rom(config_rom)
{ }
Vfs::File_system &vfs() { return _vfs_env.root_dir(); }
@ -77,18 +51,12 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
** Libc::Env interface **
*************************/
Vfs::Env &vfs_env() override {
return _vfs_env; }
void _with_config(With_config::Ft const &fn) const override
{
fn(_config_rom.xml());
}
Xml_node libc_config() override {
return _libc_config(); }
/*************************************
** Libc::Config_accessor interface **
*************************************/
Xml_node config() const override { return _config.xml(); }
Vfs::Env &vfs_env() override { return _vfs_env; }
/***************************

View File

@ -18,13 +18,16 @@
#include <base/env.h>
#include <base/heap.h>
#include <util/xml_node.h>
#include <util/callable.h>
#include <vfs/types.h> /* for 'MAX_PATH_LEN' */
/* libc includes */
#include <setjmp.h> /* for 'jmp_buf' type */
#include <libc/component.h>
/* libc-internal includes */
#include <internal/types.h>
#include <internal/config.h>
namespace Libc {
@ -41,7 +44,6 @@ namespace Libc {
struct Timer_accessor;
struct Cwd;
struct Atexit;
struct Config_accessor;
/**
* Support for shared libraries
@ -88,12 +90,7 @@ namespace Libc {
/**
* Support for getpwent
*/
void init_passwd(Xml_node);
/**
* Set libc config node
*/
void libc_config_init(Xml_node node);
void init_passwd(Xml_node const &);
/**
* Malloc allocator
@ -114,8 +111,8 @@ namespace Libc {
/**
* Socket fs
*/
void init_socket_fs(Monitor &, File_descriptor_allocator &);
void init_socket_operations(File_descriptor_allocator &);
void init_socket_fs(Monitor &, File_descriptor_allocator &, Config const &);
void init_socket_operations(File_descriptor_allocator &, Config const &);
/**
* Pthread/semaphore support
@ -125,11 +122,6 @@ namespace Libc {
Genode::Allocator &);
void init_semaphore_support(Timer_accessor &);
struct Config_accessor : Interface
{
virtual Xml_node config() const = 0;
};
/**
* Fork mechanism
*/
@ -164,6 +156,11 @@ namespace Libc {
* Kqueue support
*/
void init_kqueue(Genode::Allocator &, Monitor &, File_descriptor_allocator &);
/**
* Random-number support
*/
void init_random(Config const &);
}
#endif /* _LIBC__INTERNAL__INIT_H_ */

View File

@ -24,7 +24,6 @@
#include <libc/select.h>
/* libc-internal includes */
#include <internal/types.h>
#include <internal/malloc_ram_allocator.h>
#include <internal/cloned_malloc_heap_range.h>
#include <internal/timer.h>
@ -44,6 +43,7 @@
#include <internal/cwd.h>
#include <internal/atexit.h>
#include <internal/rtc.h>
#include <internal/config.h>
namespace Libc {
class Kernel;
@ -169,38 +169,36 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
}
};
Attached_rom_dataspace _config_rom { _env, "config" };
Config const _config = Config::from_xml(_config_rom.xml());
void _with_libc_config(auto const &fn) const
{
_config_rom.xml().with_sub_node("libc",
[&] (Xml_node const &libc) { fn(libc); },
[&] { fn( Xml_node { "<libc/>" } ); });
}
void _with_libc_sub_config(char const *tag, auto const &fn) const
{
_with_libc_config([&] (Xml_node const &libc) {
libc.with_sub_node(tag,
[&] (Xml_node const pthread) { fn(pthread); },
[&] { fn(Xml_node(String<64>("<", tag, "/>").string())); }); });
};
Vfs_user _vfs_user { _io_progressed };
Env_implementation _libc_env { _env, _heap, _vfs_user };
Constructible<Vfs::Simple_env> _vfs_env { };
bool const _update_mtime = _libc_env.libc_config().attribute_value("update_mtime", true);
bool const _vfs_env_initialized = (
with_vfs_config(_config_rom.xml(), [&] (Xml_node const &vfs_config) {
_vfs_env.construct(_env, _heap, vfs_config, _vfs_user); }), true );
Vfs_plugin _vfs { _libc_env, _fd_alloc, _libc_env.vfs_env(), _heap, *this,
_update_mtime ? Vfs_plugin::Update_mtime::YES
: Vfs_plugin::Update_mtime::NO,
*this /* current_real_time */,
_libc_env.config() };
Env_implementation _libc_env { _env, *_vfs_env, _config_rom };
bool const _cloned = _libc_env.libc_config().attribute_value("cloned", false);
pid_t const _pid = _libc_env.libc_config().attribute_value("pid", 0U);
Xml_node _passwd_config()
{
return _libc_env.libc_config().has_sub_node("passwd")
? _libc_env.libc_config().sub_node("passwd")
: Xml_node("<empty/>");
}
Xml_node _pthread_config()
{
return _libc_env.libc_config().has_sub_node("pthread")
? _libc_env.libc_config().sub_node("pthread")
: Xml_node("<pthread/>");
}
using Config_attr = String<Vfs::MAX_PATH_LEN>;
Config_attr const _rtc_path = _libc_env.libc_config().attribute_value("rtc", Config_attr());
Vfs_plugin _vfs { _fd_alloc, _heap, _config, *_vfs_env, *this, *this };
Constructible<Rtc> _rtc { };
@ -214,7 +212,7 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
void _handle_user_interrupt();
Signal _signal { _pid };
Signal _signal { _config.pid };
Atexit _atexit { _heap };
@ -229,11 +227,8 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
addr_t _kernel_stack = Thread::mystack().top;
size_t _user_stack_size();
void *_user_stack = {
_myself.alloc_secondary_stack(_myself.name().string(),
_user_stack_size()) };
void *_user_stack = _myself.alloc_secondary_stack(_myself.name().string(),
_config.stack_size);
enum State { KERNEL, USER };
@ -437,7 +432,7 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
if (!_setjmp(_kernel_context)) {
/* _setjmp() returned directly -> switch to user stack and call application code */
if (_cloned) {
if (_config.cloned) {
_main_monitor_job->complete();
_switch_to_user();
} else {
@ -683,13 +678,13 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
bool has_real_time() const override
{
return (_rtc_path != "");
return (_config.rtc.length() > 1);
}
timespec current_real_time() override
{
if (!_rtc.constructed())
_rtc.construct(_vfs, _heap, _rtc_path, *this);
_rtc.construct(_vfs, _heap, _config.rtc, *this);
return _rtc->read(current_time());
}

View File

@ -19,6 +19,9 @@
#include <base/allocator.h>
#include <base/ram_allocator.h>
/* libc-internal includes */
#include <internal/types.h>
namespace Libc { struct Malloc_ram_allocator; }

View File

@ -29,6 +29,8 @@
#include <internal/plugin.h>
#include <internal/fd_alloc.h>
#include <internal/errno.h>
#include <internal/config.h>
#include <internal/current_time.h>
namespace Libc { class Vfs_plugin; }
@ -84,11 +86,10 @@ class Libc::Vfs_plugin final : public Plugin
File_descriptor_allocator &_fd_alloc;
Genode::Allocator &_alloc;
Vfs::File_system &_root_fs;
Constructible<Genode::Directory> _root_dir { };
Genode::Directory _root_dir;
Vfs::Read_ready_response_handler &_response_handler;
Update_mtime const _update_mtime;
Config const &_config;
Current_real_time &_current_real_time;
bool const _pipe_configured;
Registry<Mmap_entry> _mmap_registry;
/*
@ -104,12 +105,7 @@ class Libc::Vfs_plugin final : public Plugin
template <typename FN>
void with_file(Absolute_path const &path, FN const &fn)
{
if (!_vfs_plugin._root_dir.constructed()) {
warning("Vfs_plugin::_root_dir unexpectedly not constructed");
return;
}
Directory &root_dir = *_vfs_plugin._root_dir;
Directory &root_dir = _vfs_plugin._root_dir;
if (path != _path && root_dir.file_exists(path.string())) {
_file.construct(root_dir, path);
@ -171,52 +167,32 @@ class Libc::Vfs_plugin final : public Plugin
template <typename FN>
void _with_info(File_descriptor &fd, FN const &fn);
static bool _init_pipe_configured(Xml_node config)
{
bool result = false;
config.with_optional_sub_node("libc", [&] (Xml_node libc_node) {
result = libc_node.has_attribute("pipe"); });
return result;
}
public:
Vfs_plugin(Libc::Env &env,
Libc::File_descriptor_allocator &fd_alloc,
Vfs::Env &vfs_env,
Vfs_plugin(File_descriptor_allocator &fd_alloc,
Genode::Allocator &alloc,
Config const &config,
Vfs::Env &vfs_env,
Vfs::Read_ready_response_handler &handler,
Update_mtime update_mtime,
Current_real_time &current_real_time,
Xml_node config)
Current_real_time &current_real_time)
:
_fd_alloc(fd_alloc),
_alloc(alloc),
_root_fs(env.vfs_env().root_dir()),
_root_fs(vfs_env.root_dir()),
_root_dir(vfs_env),
_response_handler(handler),
_update_mtime(update_mtime),
_current_real_time(current_real_time),
_pipe_configured(_init_pipe_configured(config))
{
if (config.has_sub_node("libc"))
_root_dir.construct(vfs_env);
}
_config(config),
_current_real_time(current_real_time)
{ }
~Vfs_plugin() final { }
template <typename FN>
void with_root_dir(FN const &fn)
{
if (_root_dir.constructed())
fn(*_root_dir);
}
void with_root_dir(auto const &fn) { fn(_root_dir); }
bool root_dir_has_dirents() const { return _root_fs.num_dirent("/") > 0; }
bool supports_access(const char *, int) override { return true; }
bool supports_mkdir(const char *, mode_t) override { return true; }
bool supports_open(const char *, int) override { return true; }
bool supports_pipe() override { return _pipe_configured; }
bool supports_pipe() override { return _config.pipe.length() > 1; }
bool supports_poll() override { return true; }
bool supports_readlink(const char *, char *, ::size_t) override { return true; }
bool supports_rename(const char *, const char *) override { return true; }

View File

@ -22,6 +22,7 @@ Libc::Kernel * Libc::Kernel::_kernel_ptr;
extern char **environ;
char const *libc_resolv_path; /* expected by res_init.c */
/**
* Blockade for main context
@ -44,17 +45,6 @@ inline void Libc::Main_blockade::wakeup()
}
size_t Libc::Kernel::_user_stack_size()
{
size_t size = Component::stack_size();
_libc_env.libc_config().with_optional_sub_node("stack", [&] (Xml_node stack) {
size = stack.attribute_value("size", Number_of_bytes(0)); });
return size;
}
void Libc::Kernel::reset_malloc_heap()
{
_malloc_ram.construct(_heap, _env.ram());
@ -81,7 +71,7 @@ void Libc::Kernel::_init_file_descriptors()
Diag_guard(Kernel &kernel) : kernel(kernel) { }
~Diag_guard() { if (show) log(kernel._libc_env.libc_config()); }
~Diag_guard() { if (show) log(kernel._config_rom.xml()); }
} diag_guard { *this };
@ -251,33 +241,34 @@ void Libc::Kernel::_init_file_descriptors()
if (_vfs.root_dir_has_dirents()) {
Xml_node const node = _libc_env.libc_config();
_config_rom.xml().with_optional_sub_node("libc", [&] (Xml_node const &node) {
using Path = String<Vfs::MAX_PATH_LEN>;
using Path = String<Vfs::MAX_PATH_LEN>;
if (node.has_attribute("cwd"))
_cwd.import(node.attribute_value("cwd", Path()).string(), _cwd.base());
if (node.has_attribute("cwd"))
_cwd.import(node.attribute_value("cwd", Path()).string(), _cwd.base());
init_fd(node, "stdin", 0, O_RDONLY);
init_fd(node, "stdout", 1, O_WRONLY);
init_fd(node, "stderr", 2, O_WRONLY);
init_fd(node, "stdin", 0, O_RDONLY);
init_fd(node, "stdout", 1, O_WRONLY);
init_fd(node, "stderr", 2, O_WRONLY);
node.for_each_sub_node("fd", [&] (Xml_node fd) {
node.for_each_sub_node("fd", [&] (Xml_node fd) {
unsigned const id = fd.attribute_value("id", 0U);
unsigned const id = fd.attribute_value("id", 0U);
bool const rd = fd.attribute_value("readable", false);
bool const wr = fd.attribute_value("writeable", false);
bool const rd = fd.attribute_value("readable", false);
bool const wr = fd.attribute_value("writeable", false);
unsigned const flags = rd ? (wr ? O_RDWR : O_RDONLY)
: (wr ? O_WRONLY : 0);
unsigned const flags = rd ? (wr ? O_RDWR : O_RDONLY)
: (wr ? O_WRONLY : 0);
if (!fd.has_attribute("path")) {
warning("unknown path for file descriptor ", id);
diag_guard.show = true;
}
if (!fd.has_attribute("path")) {
warning("unknown path for file descriptor ", id);
diag_guard.show = true;
}
init_fd(fd, "path", id, flags);
init_fd(fd, "path", id, flags);
});
});
/* prevent use of IDs of stdin, stdout, and stderr for other files */
@ -360,12 +351,14 @@ void Libc::Kernel::_clone_state_from_parent()
* the shared-memory buffer of the clone session may otherwise potentially
* interfere with such a heap region.
*/
_libc_env.libc_config().for_each_sub_node("heap", [&] (Xml_node node) {
Range const range = range_attr(node);
new (_heap)
Registered<Cloned_malloc_heap_range>(_cloned_heap_ranges,
_env.ram(), _env.rm(),
range); });
_with_libc_config([&] (Xml_node const &libc) {
libc.for_each_sub_node("heap", [&] (Xml_node const &node) {
Range const range = range_attr(node);
new (_heap)
Registered<Cloned_malloc_heap_range>(_cloned_heap_ranges,
_env.ram(), _env.rm(),
range); });
});
_clone_connection.construct(_env);
@ -381,34 +374,36 @@ void Libc::Kernel::_clone_state_from_parent()
_clone_connection->memory_content(&_main_monitor_job, sizeof(_main_monitor_job));
_valid_user_context = true;
_libc_env.libc_config().for_each_sub_node([&] (Xml_node node) {
auto copy_from_parent = [&] (Range range)
{
_clone_connection->memory_content((void *)range.start, range.num_bytes);
};
auto copy_from_parent = [&] (Range range)
{
_clone_connection->memory_content((void *)range.start, range.num_bytes);
};
_with_libc_config([&] (Xml_node const &libc) {
libc.for_each_sub_node([&] (Xml_node const &node) {
/* clone application stack */
if (node.type() == "stack")
copy_from_parent(range_attr(node));
/* clone RW segment of a shared library or the binary */
if (node.type() == "rw") {
using Name = String<64>;
Name const name = node.attribute_value("name", Name());
/*
* The blacklisted segments are initialized via the
* regular startup of the child.
*/
bool const blacklisted = (name == "ld.lib.so")
|| (name == "libc.lib.so")
|| (name == "libm.lib.so")
|| (name == "posix.lib.so")
|| (strcmp(name.string(), "vfs", 3) == 0);
if (!blacklisted)
/* clone application stack */
if (node.type() == "stack")
copy_from_parent(range_attr(node));
}
/* clone RW segment of a shared library or the binary */
if (node.type() == "rw") {
using Name = String<64>;
Name const name = node.attribute_value("name", Name());
/*
* The blacklisted segments are initialized via the
* regular startup of the child.
*/
bool const blacklisted = (name == "ld.lib.so")
|| (name == "libc.lib.so")
|| (name == "libm.lib.so")
|| (name == "posix.lib.so")
|| (strcmp(name.string(), "vfs", 3) == 0);
if (!blacklisted)
copy_from_parent(range_attr(node));
}
});
});
/* import application-heap state from parent */
@ -484,6 +479,8 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
:
_env(env), _heap(heap)
{
libc_resolv_path = _config.nameserver.string();
init_atexit(_atexit);
_atexit_fd_alloc_ptr = &_fd_alloc;
@ -491,11 +488,13 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
init_semaphore_support(_timer_accessor);
init_pthread_support(*this, _timer_accessor);
init_pthread_support(env.cpu(), _pthread_config(), _heap);
_with_libc_sub_config("pthread", [&] (Xml_node const &pthread_config) {
init_pthread_support(env.cpu(), pthread_config, _heap); });
_env.ep().register_io_progress_handler(*this);
if (_cloned) {
if (_config.cloned) {
_clone_state_from_parent();
} else {
@ -503,7 +502,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
init_malloc(*_malloc_heap);
}
init_fork(_env, _fd_alloc, _libc_env, _heap, *_malloc_heap, _pid, *this,
init_fork(_env, _fd_alloc, _libc_env, _heap, *_malloc_heap, _config.pid, *this,
_signal, _binary_name);
init_execve(_env, _heap, _user_stack, *this, _binary_name, _fd_alloc);
init_plugin(*this);
@ -515,11 +514,15 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
init_alarm(_timer_accessor, _signal);
init_poll(_signal, *this, _fd_alloc);
init_select(*this);
init_socket_fs(*this, _fd_alloc);
init_socket_operations(_fd_alloc);
init_passwd(_passwd_config());
init_socket_fs(*this, _fd_alloc, _config);
init_socket_operations(_fd_alloc, _config);
_with_libc_sub_config("passwd", [&] (Xml_node const &passwd_config) {
init_passwd(passwd_config); });
init_signal(_signal);
init_kqueue(_heap, *this, _fd_alloc);
init_random(_config);
_init_file_descriptors();
@ -535,6 +538,6 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
* pipe reference counter may reach an intermediate value of zero,
* triggering the destruction of the pipe.
*/
if (_cloned)
if (_config.cloned)
_clone_connection.destruct();
}

View File

@ -45,7 +45,6 @@
namespace Libc {
extern char const *config_socket();
bool read_ready_from_kernel(File_descriptor *);
bool write_ready_from_kernel(File_descriptor *);
}
@ -53,11 +52,15 @@ namespace Libc {
static Libc::Monitor *_monitor_ptr;
static Libc::Config const *_config_ptr;
void Libc::init_socket_fs(Monitor &monitor, File_descriptor_allocator &fd_alloc)
void Libc::init_socket_fs(Monitor &monitor, File_descriptor_allocator &fd_alloc,
Config const &config)
{
_monitor_ptr = &monitor;
_fd_alloc_ptr = &fd_alloc;
_config_ptr = &config;
}
@ -148,7 +151,7 @@ struct Libc::Socket_fs::Context : Plugin_context
}
Absolute_path const _path {
_read_socket_path().base(), config_socket() };
_read_socket_path().base(), _config_ptr->socket.string() };
enum Fd { DATA, PEEK, CONNECT, BIND, LISTEN, ACCEPT, LOCAL, REMOTE, MAX };
@ -1163,7 +1166,7 @@ extern "C" int socket_fs_shutdown(int libc_fd, int how)
extern "C" int socket_fs_socket(int domain, int type, int protocol)
{
Socket_fs::Absolute_path path(config_socket());
Socket_fs::Absolute_path path(_config_ptr->socket.string());
if (path == "") {
error(__func__, ": socket fs not mounted");
@ -1266,7 +1269,7 @@ extern "C" int getifaddrs(struct ifaddrs **ifap)
using Socket_fs::Absolute_path;
Absolute_path const root(config_socket());
Absolute_path const root(_config_ptr->socket.string());
if (read_ifaddr_file(address, Absolute_path("address", root.base())))
return -1;

View File

@ -31,15 +31,18 @@ extern "C" {
#include <internal/init.h>
void Libc::init_socket_operations(Libc::File_descriptor_allocator &fd_alloc)
using namespace Libc;
static Config const *_config_ptr;
void Libc::init_socket_operations(Libc::File_descriptor_allocator &fd_alloc,
Config const &config)
{
_fd_alloc_ptr = &fd_alloc;
_config_ptr = &config;
}
using namespace Libc;
#define __SYS_(ret_type, name, args, body) \
extern "C" {\
ret_type __sys_##name args body \
@ -47,8 +50,6 @@ using namespace Libc;
ret_type name args __attribute__((alias("__sys_" #name))); \
} \
namespace Libc { extern char const *config_socket(); }
/***********************
** Address functions **
@ -56,7 +57,7 @@ namespace Libc { extern char const *config_socket(); }
extern "C" int getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_getpeername(libc_fd, addr, addrlen);
return Libc::Errno(ENOTSOCK);
@ -69,7 +70,7 @@ int _getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen);
extern "C" int getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_getsockname(libc_fd, addr, addrlen);
FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen);
@ -86,7 +87,7 @@ int _getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen);
__SYS_(int, accept, (int libc_fd, sockaddr *addr, socklen_t *addrlen),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_accept(libc_fd, addr, addrlen);
File_descriptor *ret_fd;
@ -103,7 +104,7 @@ __SYS_(int, accept4, (int libc_fd, struct sockaddr *addr, socklen_t *addrlen, in
extern "C" int bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_bind(libc_fd, addr, addrlen);
FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen);
@ -116,7 +117,7 @@ int _bind(int libc_fd, sockaddr const *addr, socklen_t addrlen);
__SYS_(int, connect, (int libc_fd, sockaddr const *addr, socklen_t addrlen),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_connect(libc_fd, addr, addrlen);
FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen);
@ -125,7 +126,7 @@ __SYS_(int, connect, (int libc_fd, sockaddr const *addr, socklen_t addrlen),
extern "C" int listen(int libc_fd, int backlog)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_listen(libc_fd, backlog);
FD_FUNC_WRAPPER(listen, libc_fd, backlog);
@ -135,7 +136,7 @@ extern "C" int listen(int libc_fd, int backlog)
__SYS_(ssize_t, recvfrom, (int libc_fd, void *buf, ::size_t len, int flags,
sockaddr *src_addr, socklen_t *src_addrlen),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_recvfrom(libc_fd, buf, len, flags, src_addr, src_addrlen);
FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, src_addrlen);
@ -144,7 +145,7 @@ __SYS_(ssize_t, recvfrom, (int libc_fd, void *buf, ::size_t len, int flags,
__SYS_(ssize_t, recv, (int libc_fd, void *buf, ::size_t len, int flags),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_recv(libc_fd, buf, len, flags);
FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags);
@ -153,7 +154,7 @@ __SYS_(ssize_t, recv, (int libc_fd, void *buf, ::size_t len, int flags),
__SYS_(ssize_t, recvmsg, (int libc_fd, msghdr *msg, int flags),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_recvmsg(libc_fd, msg, flags);
FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags);
@ -163,7 +164,7 @@ __SYS_(ssize_t, recvmsg, (int libc_fd, msghdr *msg, int flags),
__SYS_(ssize_t, sendto, (int libc_fd, void const *buf, ::size_t len, int flags,
sockaddr const *dest_addr, socklen_t dest_addrlen),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_sendto(libc_fd, buf, len, flags, dest_addr, dest_addrlen);
FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, dest_addrlen);
@ -172,7 +173,7 @@ __SYS_(ssize_t, sendto, (int libc_fd, void const *buf, ::size_t len, int flags,
extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_send(libc_fd, buf, len, flags);
FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags);
@ -182,7 +183,7 @@ extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
extern "C" int getsockopt(int libc_fd, int level, int optname,
void *optval, socklen_t *optlen)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_getsockopt(libc_fd, level, optname, optval, optlen);
FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen);
@ -197,7 +198,7 @@ int _getsockopt(int libc_fd, int level, int optname,
extern "C" int setsockopt(int libc_fd, int level, int optname,
void const *optval, socklen_t optlen)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_setsockopt(libc_fd, level, optname, optval, optlen);
FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen);
@ -211,7 +212,7 @@ int _setsockopt(int libc_fd, int level, int optname,
extern "C" int shutdown(int libc_fd, int how)
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_shutdown(libc_fd, how);
FD_FUNC_WRAPPER(shutdown, libc_fd, how);
@ -219,7 +220,7 @@ extern "C" int shutdown(int libc_fd, int how)
__SYS_(int, socket, (int domain, int type, int protocol),
{
if (*config_socket())
if (_config_ptr->socket.length() > 1)
return socket_fs_socket(domain, type, protocol);
Plugin *plugin;

View File

@ -138,81 +138,8 @@ static void vfs_stat_to_libc_stat_struct(Vfs::Directory_service::Stat const &src
}
static Genode::Xml_node *_config_node;
char const *libc_resolv_path;
namespace Libc {
Xml_node config() __attribute__((weak));
Xml_node config()
{
if (!_config_node) {
error("libc config not initialized - aborting");
exit(1);
}
return *_config_node;
}
class Config_attr
{
private:
using Value = String<Vfs::MAX_PATH_LEN>;
Value const _value;
public:
Config_attr(char const *attr_name, char const *default_value)
:
_value(config().attribute_value(attr_name,
Value(default_value)))
{ }
char const *string() const { return _value.string(); }
};
char const *config_pipe() __attribute__((weak));
char const *config_pipe()
{
static Config_attr attr("pipe", "");
return attr.string();
}
char const *config_rng() __attribute__((weak));
char const *config_rng()
{
static Config_attr rng("rng", "");
return rng.string();
}
char const *config_socket() __attribute__((weak));
char const *config_socket()
{
static Config_attr socket("socket", "");
return socket.string();
}
char const *config_nameserver_file() __attribute__((weak));
char const *config_nameserver_file()
{
static Genode::String<Vfs::MAX_PATH_LEN> default_value {
config_socket(), "/nameserver" };
static Config_attr ns_file("nameserver_file",
default_value.string());
return ns_file.string();
}
void libc_config_init(Xml_node node)
{
static Xml_node config = node;
_config_node = &config;
libc_resolv_path = config_nameserver_file();
}
bool read_ready_from_kernel(File_descriptor *fd)
{
Vfs::Vfs_handle *handle = vfs_handle(fd);
@ -255,10 +182,10 @@ void Libc::Vfs_plugin::_with_info(File_descriptor &fd, FN const &fn)
char buffer[4096] { };
Byte_range_ptr range(buffer,
min((size_t)(_root_dir->file_size(path.string())),
min((size_t)(_root_dir.file_size(path.string())),
sizeof(buffer)));
with_xml_file_content(file, range, [&] (Xml_node node) { fn(node); });
with_xml_file_content(file, range, [&] (Xml_node const &node) { fn(node); });
});
}
@ -551,13 +478,14 @@ struct Sync
Vfs::Vfs_handle &vfs_handle;
Vfs::Timestamp mtime { };
Sync(Vfs::Vfs_handle &vfs_handle, Libc::Vfs_plugin::Update_mtime update_mtime,
struct Attr { bool update_mtime; };
Sync(Vfs::Vfs_handle &vfs_handle, Attr const attr,
Libc::Current_real_time &current_real_time)
:
vfs_handle(vfs_handle)
{
if (update_mtime == Libc::Vfs_plugin::Update_mtime::NO
|| !current_real_time.has_real_time()) {
if (!attr.update_mtime || !current_real_time.has_real_time()) {
state = TIMESTAMP_UPDATED;
@ -599,7 +527,7 @@ int Libc::Vfs_plugin::close_from_kernel(File_descriptor *fd)
if ((fd->modified) || (fd->flags & O_CREAT)) {
/* XXX mtime not updated here */
Sync sync { *handle, Update_mtime::NO, _current_real_time };
Sync sync { *handle, { .update_mtime = false }, _current_real_time };
while (!sync.complete()) {
Libc::Kernel::kernel().wakeup_remote_peers();
@ -618,7 +546,7 @@ int Libc::Vfs_plugin::close(File_descriptor *fd)
{
Vfs::Vfs_handle *handle = vfs_handle(fd);
Sync sync { *handle , _update_mtime, _current_real_time };
Sync sync { *handle, { .update_mtime = _config.update_mtime }, _current_real_time };
monitor().monitor([&] {
if ((fd->modified) || (fd->flags & O_CREAT))
@ -711,7 +639,7 @@ int Libc::Vfs_plugin::fstat(File_descriptor *fd, struct stat *buf)
Vfs::Vfs_handle *handle = vfs_handle(fd);
if (fd->modified) {
Sync sync { *handle , _update_mtime, _current_real_time };
Sync sync { *handle , { .update_mtime = _config.update_mtime }, _current_real_time };
monitor().monitor([&] {
if (!sync.complete()) {
@ -1108,7 +1036,7 @@ Libc::Vfs_plugin::_ioctl_tio(File_descriptor *fd, unsigned long request, char *a
if (request == TIOCGWINSZ) {
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() == "terminal") {
::winsize *winsize = (::winsize *)argp;
winsize->ws_row = info.attribute_value("rows", 25U);
@ -1169,7 +1097,7 @@ Libc::Vfs_plugin::_ioctl_dio(File_descriptor *fd, unsigned long request, char *a
if (request == DIOCGMEDIASIZE) {
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() == "block") {
size_t const size =
@ -1232,7 +1160,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1268,7 +1196,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
@ -1300,7 +1228,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
int play_underruns = 0;
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1347,7 +1275,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1372,7 +1300,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1434,7 +1362,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1547,7 +1475,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
if (!argp) return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1610,7 +1538,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1663,7 +1591,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1753,7 +1681,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
bool legacy_oss = false;
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") return;
/* assume legacy if version is not set, current is 2 */
@ -1779,7 +1707,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
}
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") {
return;
}
@ -1818,7 +1746,7 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char
auto result = Fn::INCOMPLETE;
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() != "oss") return;
@ -1868,7 +1796,7 @@ Libc::Vfs_plugin::_ioctl_tapctl(File_descriptor *fd, unsigned long request, char
ifreq *ifr = reinterpret_cast<ifreq*>(argp);
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() == "tap") {
String<IFNAMSIZ> name = info.attribute_value("name", String<IFNAMSIZ> { });
copy_cstring(ifr->ifr_name, name.string(), IFNAMSIZ);
@ -1884,7 +1812,7 @@ Libc::Vfs_plugin::_ioctl_tapctl(File_descriptor *fd, unsigned long request, char
return { true, EINVAL };
monitor().monitor([&] {
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() == "tap") {
Net::Mac_address mac = info.attribute_value("mac_addr", Net::Mac_address { });
mac.copy(argp);
@ -1913,7 +1841,7 @@ Libc::Vfs_plugin::_ioctl_tapctl(File_descriptor *fd, unsigned long request, char
monitor().monitor([&] {
/* check whether mac address changed, return ENOTSUP if not */
_with_info(*fd, [&] (Xml_node info) {
_with_info(*fd, [&] (Xml_node const &info) {
if (info.type() == "tap") {
if (!info.has_attribute("mac_addr"))
result = ENOTSUP;
@ -2026,7 +1954,7 @@ int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *ar
int Libc::Vfs_plugin::ftruncate(File_descriptor *fd, ::off_t length)
{
Vfs::Vfs_handle *handle = vfs_handle(fd);
Sync sync { *handle, _update_mtime, _current_real_time };
Sync sync { *handle, { .update_mtime = _config.update_mtime }, _current_real_time };
bool succeeded = false;
int result_errno = 0;
@ -2106,7 +2034,7 @@ int Libc::Vfs_plugin::fsync(File_descriptor *fd)
if (!fd->modified)
return 0;
Sync sync { *handle, _update_mtime, _current_real_time };
Sync sync { *handle, { .update_mtime = _config.update_mtime }, _current_real_time };
monitor().monitor([&] {
if (!sync.complete()) {
@ -2167,8 +2095,8 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
}
/* must be done outside the monitor because constructor needs libc I/O */
sync.construct(*handle, _update_mtime, _current_real_time);
sync.construct(*handle, Sync::Attr { .update_mtime = _config.update_mtime },
_current_real_time);
{
bool succeeded { false };
int result_errno { 0 };
@ -2520,7 +2448,7 @@ int Libc::Vfs_plugin::munmap(void *addr, ::size_t)
int Libc::Vfs_plugin::pipe(Libc::File_descriptor *pipefdo[2])
{
Absolute_path base_path(Libc::config_pipe());
Absolute_path base_path(_config.pipe);
if (base_path == "") {
error(__func__, ": pipe fs not mounted");
return Errno(EACCES);

View File

@ -32,6 +32,7 @@ $(MIRROR_FROM_PORT_DIR):
MIRROR_FROM_LIBPORTS := lib/mk/libc-mem.mk \
lib/mk/libc-common.inc \
src/lib/libc/internal/config.h \
src/lib/libc/internal/init.h \
src/lib/libc/internal/mem_alloc.h \
src/lib/libc/internal/monitor.h \

View File

@ -38,6 +38,7 @@ MIRROR_FROM_LIBPORTS := \
lib/mk/qemu-usb-webcam.inc \
lib/mk/spec/x86_32/qemu-usb.mk \
lib/mk/spec/x86_64/qemu-usb.mk \
src/lib/libc/internal/config.h \
src/lib/libc/internal/init.h \
src/lib/libc/internal/mem_alloc.h \
src/lib/libc/internal/monitor.h \