mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 09:21:49 +00:00
Support for suspendable read in VFS and libC
The support has two parts. First, a VFS plugin now gets passed an I/O-response handler callback on construction, which informs users of the VFS that an I/O event occurred. This enables, for example, the libC to check if blocking read can be completed. Further, the VFS file I/O interface provides now functions for suspendable reads, i.e., queue_read() and complete_read().
This commit is contained in:
parent
e5d6c06f58
commit
c0d61858c3
@ -43,6 +43,7 @@ namespace Libc {
|
|||||||
class Timer_accessor;
|
class Timer_accessor;
|
||||||
class Timeout;
|
class Timeout;
|
||||||
class Timeout_handler;
|
class Timeout_handler;
|
||||||
|
class Io_response_handler;
|
||||||
|
|
||||||
using Microseconds = Genode::Time_source::Microseconds;
|
using Microseconds = Genode::Time_source::Microseconds;
|
||||||
}
|
}
|
||||||
@ -79,10 +80,11 @@ class Libc::Env_implementation : public Libc::Env
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Env_implementation(Genode::Env &env, Genode::Allocator &alloc)
|
Env_implementation(Genode::Env &env, Genode::Allocator &alloc,
|
||||||
|
Vfs::Io_response_handler &io_response_handler)
|
||||||
:
|
:
|
||||||
_env(env),
|
_env(env),
|
||||||
_vfs(_env, alloc, _vfs_config(),
|
_vfs(_env, alloc, _vfs_config(), io_response_handler,
|
||||||
Vfs::global_file_system_factory())
|
Vfs::global_file_system_factory())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -301,6 +303,15 @@ struct Libc::Pthreads
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Libc::Io_response_handler : Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
void handle_io_response() override
|
||||||
|
{
|
||||||
|
Libc::resume_all();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* internal utility */
|
/* internal utility */
|
||||||
static void resumed_callback();
|
static void resumed_callback();
|
||||||
static void suspended_callback();
|
static void suspended_callback();
|
||||||
@ -322,7 +333,8 @@ struct Libc::Kernel
|
|||||||
|
|
||||||
Genode::Env &_env;
|
Genode::Env &_env;
|
||||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||||
Env_implementation _libc_env { _env, _heap };
|
Io_response_handler _io_response_handler;
|
||||||
|
Env_implementation _libc_env { _env, _heap, _io_response_handler };
|
||||||
Vfs_plugin _vfs { _libc_env, _heap };
|
Vfs_plugin _vfs { _libc_env, _heap };
|
||||||
|
|
||||||
jmp_buf _kernel_context;
|
jmp_buf _kernel_context;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
/* libc-internal includes */
|
/* libc-internal includes */
|
||||||
#include <libc_mem_alloc.h>
|
#include <libc_mem_alloc.h>
|
||||||
#include "libc_errno.h"
|
#include "libc_errno.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
static Vfs::Vfs_handle *vfs_handle(Libc::File_descriptor *fd)
|
static Vfs::Vfs_handle *vfs_handle(Libc::File_descriptor *fd)
|
||||||
@ -288,14 +289,27 @@ ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
|||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
|
|
||||||
Vfs::file_size out_count = 0;
|
Vfs::file_size out_count = 0;
|
||||||
|
Result out_result = Result::READ_OK;
|
||||||
|
|
||||||
switch (handle->fs().read(handle, (char *)buf, count, out_count)) {
|
while (!handle->fs().queue_read(handle, (char *)buf, count,
|
||||||
case Result::READ_ERR_AGAIN: errno = EAGAIN; return -1;
|
out_result, out_count))
|
||||||
case Result::READ_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; return -1;
|
Libc::suspend();
|
||||||
case Result::READ_ERR_INVALID: errno = EINVAL; return -1;
|
|
||||||
case Result::READ_ERR_IO: errno = EIO; return -1;
|
while (out_result == Result::READ_QUEUED) {
|
||||||
case Result::READ_ERR_INTERRUPT: errno = EINTR; return -1;
|
out_result = handle->fs().complete_read(handle, (char *)buf, count, out_count);
|
||||||
|
if (out_result == Result::READ_QUEUED)
|
||||||
|
Libc::suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (out_result) {
|
||||||
|
case Result::READ_ERR_AGAIN: return Errno(EAGAIN);
|
||||||
|
case Result::READ_ERR_WOULD_BLOCK: return Errno(EWOULDBLOCK);
|
||||||
|
case Result::READ_ERR_INVALID: return Errno(EINVAL);
|
||||||
|
case Result::READ_ERR_IO: return Errno(EIO);
|
||||||
|
case Result::READ_ERR_INTERRUPT: return Errno(EINTR);
|
||||||
case Result::READ_OK: break;
|
case Result::READ_OK: break;
|
||||||
|
|
||||||
|
case Result::READ_QUEUED: /* handled above, so never reached */ break;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->advance_seek(out_count);
|
handle->advance_seek(out_count);
|
||||||
|
@ -209,6 +209,7 @@ class Vfs::Dir_file_system : public File_system
|
|||||||
Dir_file_system(Genode::Env &env,
|
Dir_file_system(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node node,
|
Genode::Xml_node node,
|
||||||
|
Io_response_handler &io_handler,
|
||||||
File_system_factory &fs_factory)
|
File_system_factory &fs_factory)
|
||||||
:
|
:
|
||||||
_first_file_system(0)
|
_first_file_system(0)
|
||||||
@ -228,11 +229,11 @@ class Vfs::Dir_file_system : public File_system
|
|||||||
/* traverse into <dir> nodes */
|
/* traverse into <dir> nodes */
|
||||||
if (sub_node.has_type("dir")) {
|
if (sub_node.has_type("dir")) {
|
||||||
_append_file_system(new (alloc)
|
_append_file_system(new (alloc)
|
||||||
Dir_file_system(env, alloc, sub_node, fs_factory));
|
Dir_file_system(env, alloc, sub_node, io_handler, fs_factory));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
File_system *fs = fs_factory.create(env, alloc, sub_node);
|
File_system *fs = fs_factory.create(env, alloc, sub_node, io_handler);
|
||||||
if (fs) {
|
if (fs) {
|
||||||
_append_file_system(fs);
|
_append_file_system(fs);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Interface for operations provided by file I/O service
|
* \brief Interface for operations provided by file I/O service
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
|
* \author Emery Hemingway
|
||||||
|
* \author Christian Helmuth
|
||||||
* \date 2011-02-17
|
* \date 2011-02-17
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2014 Genode Labs GmbH
|
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -16,10 +18,17 @@
|
|||||||
|
|
||||||
namespace Vfs {
|
namespace Vfs {
|
||||||
class Vfs_handle;
|
class Vfs_handle;
|
||||||
|
struct Io_response_handler;
|
||||||
struct File_io_service;
|
struct File_io_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
virtual void handle_io_response() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Vfs::File_io_service
|
struct Vfs::File_io_service
|
||||||
{
|
{
|
||||||
enum General_error { ERR_FD_INVALID, NUM_GENERAL_ERRORS };
|
enum General_error { ERR_FD_INVALID, NUM_GENERAL_ERRORS };
|
||||||
@ -44,11 +53,29 @@ struct Vfs::File_io_service
|
|||||||
|
|
||||||
enum Read_result { READ_ERR_AGAIN, READ_ERR_WOULD_BLOCK,
|
enum Read_result { READ_ERR_AGAIN, READ_ERR_WOULD_BLOCK,
|
||||||
READ_ERR_INVALID, READ_ERR_IO,
|
READ_ERR_INVALID, READ_ERR_IO,
|
||||||
READ_ERR_INTERRUPT, READ_OK };
|
READ_ERR_INTERRUPT, READ_QUEUED,
|
||||||
|
READ_OK };
|
||||||
|
|
||||||
virtual Read_result read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
virtual Read_result read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
file_size &out_count) = 0;
|
file_size &out_count) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from handle with potential queueing of operation
|
||||||
|
*
|
||||||
|
* \return false if queue is full
|
||||||
|
*/
|
||||||
|
virtual bool queue_read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
|
Read_result &out_result, file_size &out_count)
|
||||||
|
{
|
||||||
|
out_result = read(vfs_handle, dst, count, out_count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Read_result complete_read(Vfs_handle *vfs_handle,
|
||||||
|
char *dst, file_size count,
|
||||||
|
file_size &out_count)
|
||||||
|
{ return read(vfs_handle, dst, count, out_count); }
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
** Ftruncate **
|
** Ftruncate **
|
||||||
|
@ -39,7 +39,8 @@ struct Vfs::File_system_factory
|
|||||||
*/
|
*/
|
||||||
virtual File_system *create(Genode::Env &env,
|
virtual File_system *create(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Xml_node config) = 0;
|
Xml_node config,
|
||||||
|
Io_response_handler &io_handler) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <base/lock.h>
|
#include <base/lock.h>
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
#include <base/printf.h>
|
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
#include <os/path.h>
|
#include <os/path.h>
|
||||||
|
|
||||||
|
@ -149,8 +149,13 @@ struct Cli_monitor::Main
|
|||||||
|
|
||||||
Heap _heap { _env.ram(), _env.rm() };
|
Heap _heap { _env.ram(), _env.rm() };
|
||||||
|
|
||||||
|
struct Io_response_handler : Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
void handle_io_response() { }
|
||||||
|
} io_response_handler;
|
||||||
|
|
||||||
/* initialize virtual file system */
|
/* initialize virtual file system */
|
||||||
Vfs::Dir_file_system _root_dir { _env, _heap, _vfs_config(),
|
Vfs::Dir_file_system _root_dir { _env, _heap, _vfs_config(), io_response_handler,
|
||||||
Vfs::global_file_system_factory() };
|
Vfs::global_file_system_factory() };
|
||||||
|
|
||||||
Subsystem_config_registry _subsystem_config_registry { _root_dir, _heap };
|
Subsystem_config_registry _subsystem_config_registry { _root_dir, _heap };
|
||||||
|
@ -114,7 +114,8 @@ class Vfs::Block_file_system : public Single_file_system
|
|||||||
|
|
||||||
Block_file_system(Genode::Env &env,
|
Block_file_system(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_BLOCK_DEVICE, name(), config),
|
Single_file_system(NODE_TYPE_BLOCK_DEVICE, name(), config),
|
||||||
_alloc(alloc),
|
_alloc(alloc),
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Genode Labs GmbH
|
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -30,6 +30,9 @@
|
|||||||
#include "zero_file_system.h"
|
#include "zero_file_system.h"
|
||||||
|
|
||||||
|
|
||||||
|
using Vfs::Io_response_handler;
|
||||||
|
|
||||||
|
|
||||||
class Default_file_system_factory : public Vfs::Global_file_system_factory
|
class Default_file_system_factory : public Vfs::Global_file_system_factory
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -57,9 +60,10 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
|
|
||||||
Vfs::File_system *create(Genode::Env &env,
|
Vfs::File_system *create(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node node) override
|
Genode::Xml_node node,
|
||||||
|
Io_response_handler &io_handler) override
|
||||||
{
|
{
|
||||||
return new (alloc) FILE_SYSTEM(env, alloc, node);
|
return new (alloc) FILE_SYSTEM(env, alloc, node, io_handler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,8 +78,9 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
|
|
||||||
Vfs::File_system *create(Genode::Env &env,
|
Vfs::File_system *create(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node node) override {
|
Genode::Xml_node node,
|
||||||
return _fs_factory.create(env, alloc, node); }
|
Io_response_handler &io_handler) override {
|
||||||
|
return _fs_factory.create(env, alloc, node, io_handler); }
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::List<Entry_base> _list;
|
Genode::List<Entry_base> _list;
|
||||||
@ -88,11 +93,12 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
|
|
||||||
Vfs::File_system *_try_create(Genode::Env &env,
|
Vfs::File_system *_try_create(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node node)
|
Genode::Xml_node node,
|
||||||
|
Io_response_handler &io_handler)
|
||||||
{
|
{
|
||||||
for (Entry_base *e = _list.first(); e; e = e->next())
|
for (Entry_base *e = _list.first(); e; e = e->next())
|
||||||
if (e->matches(node))
|
if (e->matches(node))
|
||||||
return e->create(env, alloc, node);
|
return e->create(env, alloc, node, io_handler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -151,12 +157,13 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
return *query_fn();
|
return *query_fn();
|
||||||
|
|
||||||
} catch (Genode::Shared_object::Invalid_rom_module) {
|
} catch (Genode::Shared_object::Invalid_rom_module) {
|
||||||
PWRN("could not open '%s'", lib_name.string());
|
Genode::warning("could not open '", lib_name, "'");
|
||||||
throw Factory_not_available();
|
throw Factory_not_available();
|
||||||
|
|
||||||
} catch (Genode::Shared_object::Invalid_symbol) {
|
} catch (Genode::Shared_object::Invalid_symbol) {
|
||||||
PWRN("could not find symbol '%s' in '%s'",
|
Genode::warning("could not find symbol '",
|
||||||
_factory_symbol(), lib_name.string());
|
Genode::Cstring(_factory_symbol()),
|
||||||
|
"' in '", lib_name, "'");
|
||||||
|
|
||||||
Genode::destroy(alloc, shared_object);
|
Genode::destroy(alloc, shared_object);
|
||||||
throw Factory_not_available();
|
throw Factory_not_available();
|
||||||
@ -181,11 +188,12 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
|
|
||||||
Vfs::File_system *create(Genode::Env &env,
|
Vfs::File_system *create(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node node) override
|
Genode::Xml_node node,
|
||||||
|
Io_response_handler &io_handler) override
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
/* try if type is handled by the currently registered fs types */
|
/* try if type is handled by the currently registered fs types */
|
||||||
if (Vfs::File_system *fs = _try_create(env, alloc, node))
|
if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
|
||||||
return fs;
|
return fs;
|
||||||
/* if the builtin fails, do not try loading an external */
|
/* if the builtin fails, do not try loading an external */
|
||||||
} catch (...) { return 0; }
|
} catch (...) { return 0; }
|
||||||
@ -194,7 +202,7 @@ class Default_file_system_factory : public Vfs::Global_file_system_factory
|
|||||||
/* probe for file system implementation available as shared lib */
|
/* probe for file system implementation available as shared lib */
|
||||||
if (_probe_external_factory(env, alloc, node)) {
|
if (_probe_external_factory(env, alloc, node)) {
|
||||||
/* try again with the new file system type loaded */
|
/* try again with the new file system type loaded */
|
||||||
if (Vfs::File_system *fs = _try_create(env, alloc, node))
|
if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
} catch (...) { }
|
} catch (...) { }
|
||||||
|
@ -153,16 +153,17 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
|
|
||||||
Fs_file_system(Genode::Env &env,
|
Fs_file_system(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
_env(env),
|
_env(env),
|
||||||
_fs_packet_alloc(&alloc),
|
_fs_packet_alloc(&alloc),
|
||||||
_label(config.attribute_value("label", Label_string())),
|
_label(config.attribute_value("label", Label_string())),
|
||||||
_root( config.attribute_value("root", Root_string())),
|
_root( config.attribute_value("root", Root_string())),
|
||||||
_fs(_fs_packet_alloc,
|
_fs(env, _fs_packet_alloc,
|
||||||
::File_system::DEFAULT_TX_BUF_SIZE,
|
|
||||||
_label.string(), _root.string(),
|
_label.string(), _root.string(),
|
||||||
config.attribute_value("writeable", true))
|
config.attribute_value("writeable", true),
|
||||||
|
::File_system::DEFAULT_TX_BUF_SIZE)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ class Vfs::Inline_file_system : public Single_file_system
|
|||||||
|
|
||||||
Inline_file_system(Genode::Env&,
|
Inline_file_system(Genode::Env&,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_FILE, name(), config),
|
Single_file_system(NODE_TYPE_FILE, name(), config),
|
||||||
_base(config.content_base()),
|
_base(config.content_base()),
|
||||||
|
@ -50,7 +50,8 @@ class Vfs::Log_file_system : public Single_file_system
|
|||||||
|
|
||||||
Log_file_system(Genode::Env &env,
|
Log_file_system(Genode::Env &env,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
||||||
_label(config.attribute_value("label", Label())),
|
_label(config.attribute_value("label", Label())),
|
||||||
|
@ -24,7 +24,8 @@ struct Vfs::Null_file_system : Single_file_system
|
|||||||
{
|
{
|
||||||
Null_file_system(Genode::Env&,
|
Null_file_system(Genode::Env&,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config)
|
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config)
|
||||||
{ }
|
{ }
|
||||||
|
@ -422,7 +422,8 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
|||||||
|
|
||||||
Ram_file_system(Genode::Env &env,
|
Ram_file_system(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node)
|
Genode::Xml_node,
|
||||||
|
Io_response_handler &)
|
||||||
: _env(env), _alloc(alloc) { }
|
: _env(env), _alloc(alloc) { }
|
||||||
|
|
||||||
~Ram_file_system() { _root.empty(_alloc); }
|
~Ram_file_system() { _root.empty(_alloc); }
|
||||||
|
@ -50,7 +50,8 @@ class Vfs::Rom_file_system : public Single_file_system
|
|||||||
|
|
||||||
Rom_file_system(Genode::Env &env,
|
Rom_file_system(Genode::Env &env,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_FILE, name(), config),
|
Single_file_system(NODE_TYPE_FILE, name(), config),
|
||||||
_label(config),
|
_label(config),
|
||||||
|
@ -32,7 +32,8 @@ class Vfs::Rtc_file_system : public Single_file_system
|
|||||||
|
|
||||||
Rtc_file_system(Genode::Env &env,
|
Rtc_file_system(Genode::Env &env,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
||||||
_rtc(env)
|
_rtc(env)
|
||||||
|
@ -33,7 +33,8 @@ class Vfs::Symlink_file_system : public Single_file_system
|
|||||||
|
|
||||||
Symlink_file_system(Genode::Env&,
|
Symlink_file_system(Genode::Env&,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler&)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_SYMLINK, "symlink", config),
|
Single_file_system(NODE_TYPE_SYMLINK, "symlink", config),
|
||||||
_target(config.attribute_value("target", Target()))
|
_target(config.attribute_value("target", Target()))
|
||||||
|
@ -344,7 +344,8 @@ class Vfs::Tar_file_system : public File_system
|
|||||||
|
|
||||||
Tar_file_system(Genode::Env &env,
|
Tar_file_system(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
_env(env), _alloc(alloc),
|
_env(env), _alloc(alloc),
|
||||||
_rom_name(config.attribute_value("name", Rom_name())),
|
_rom_name(config.attribute_value("name", Rom_name())),
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
* \brief Terminal file system
|
* \brief Terminal file system
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
|
* \author Christian Helmuth
|
||||||
* \date 2012-05-23
|
* \date 2012-05-23
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2016 Genode Labs GmbH
|
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -17,6 +18,8 @@
|
|||||||
|
|
||||||
#include <terminal_session/connection.h>
|
#include <terminal_session/connection.h>
|
||||||
#include <vfs/single_file_system.h>
|
#include <vfs/single_file_system.h>
|
||||||
|
#include <base/signal.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Vfs { class Terminal_file_system; }
|
namespace Vfs { class Terminal_file_system; }
|
||||||
|
|
||||||
@ -28,33 +31,40 @@ class Vfs::Terminal_file_system : public Single_file_system
|
|||||||
typedef Genode::String<64> Label;
|
typedef Genode::String<64> Label;
|
||||||
Label _label;
|
Label _label;
|
||||||
|
|
||||||
Terminal::Connection _terminal;
|
Genode::Env &_env;
|
||||||
|
Io_response_handler &_io_handler;
|
||||||
|
|
||||||
|
Terminal::Connection _terminal { _env, _label.string() };
|
||||||
|
|
||||||
|
Genode::Signal_handler<Terminal_file_system> _read_avail_handler {
|
||||||
|
_env.ep(), *this, &Terminal_file_system::_handle_read_avail };
|
||||||
|
|
||||||
|
void _handle_read_avail() { _io_handler.handle_io_response(); }
|
||||||
|
|
||||||
|
Read_result _read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
|
file_size &out_count)
|
||||||
|
{
|
||||||
|
if (_terminal.avail()) {
|
||||||
|
out_count = _terminal.read(dst, count);
|
||||||
|
return READ_OK;
|
||||||
|
} else {
|
||||||
|
return READ_QUEUED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Terminal_file_system(Genode::Env &env,
|
Terminal_file_system(Genode::Env &env,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &io_handler)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config),
|
||||||
_label(config.attribute_value("label", Label())),
|
_label(config.attribute_value("label", Label())),
|
||||||
_terminal(env, _label.string())
|
_env(env), _io_handler(io_handler)
|
||||||
{
|
{
|
||||||
/*
|
/* register for read-avail notification */
|
||||||
* Wait for connection-established signal
|
_terminal.read_avail_sigh(_read_avail_handler);
|
||||||
*/
|
|
||||||
|
|
||||||
/* create signal receiver, just for the single signal */
|
|
||||||
Genode::Signal_context sig_ctx;
|
|
||||||
Genode::Signal_receiver sig_rec;
|
|
||||||
Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
|
|
||||||
|
|
||||||
/* register signal handler */
|
|
||||||
_terminal.connected_sigh(sig_cap);
|
|
||||||
|
|
||||||
/* wati for signal */
|
|
||||||
sig_rec.wait_for_signal();
|
|
||||||
sig_rec.dissolve(&sig_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *name() { return "terminal"; }
|
static const char *name() { return "terminal"; }
|
||||||
@ -78,6 +88,19 @@ class Vfs::Terminal_file_system : public Single_file_system
|
|||||||
return READ_OK;
|
return READ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool queue_read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
|
Read_result &out_result, file_size &out_count) override
|
||||||
|
{
|
||||||
|
out_result = _read(vfs_handle, dst, count, out_count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
|
file_size &out_count) override
|
||||||
|
{
|
||||||
|
return _read(vfs_handle, dst, count, out_count);
|
||||||
|
}
|
||||||
|
|
||||||
Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size) override
|
Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size) override
|
||||||
{
|
{
|
||||||
return FTRUNCATE_OK;
|
return FTRUNCATE_OK;
|
||||||
|
@ -24,7 +24,8 @@ struct Vfs::Zero_file_system : Single_file_system
|
|||||||
{
|
{
|
||||||
Zero_file_system(Genode::Env&,
|
Zero_file_system(Genode::Env&,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Io_response_handler &)
|
||||||
:
|
:
|
||||||
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config)
|
Single_file_system(NODE_TYPE_CHAR_DEVICE, name(), config)
|
||||||
{ }
|
{ }
|
||||||
|
@ -35,6 +35,7 @@ namespace Vfs_server {
|
|||||||
|
|
||||||
class Session_component;
|
class Session_component;
|
||||||
class Root;
|
class Root;
|
||||||
|
class Io_response_handler;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -464,6 +465,15 @@ class Vfs_server::Session_component :
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Vfs_server::Io_response_handler : Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
void handle_io_response() override
|
||||||
|
{
|
||||||
|
Genode::log(__func__, " called");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Vfs_server::Root :
|
class Vfs_server::Root :
|
||||||
public Genode::Root_component<Session_component>
|
public Genode::Root_component<Session_component>
|
||||||
{
|
{
|
||||||
@ -484,8 +494,11 @@ class Vfs_server::Root :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vfs::Dir_file_system _vfs
|
Io_response_handler _io_response_handler;
|
||||||
{ _env, _heap, vfs_config(), Vfs::global_file_system_factory() };
|
|
||||||
|
Vfs::Dir_file_system _vfs {
|
||||||
|
_env, _heap, vfs_config(), _io_response_handler,
|
||||||
|
Vfs::global_file_system_factory() };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ inline void assert_read(Vfs::File_io_service::Read_result r)
|
|||||||
typedef Vfs::File_io_service::Read_result Result;
|
typedef Vfs::File_io_service::Read_result Result;
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case Result::READ_OK: return;
|
case Result::READ_OK: return;
|
||||||
|
case Result::READ_QUEUED:
|
||||||
|
error("READ_QUEUED"); break;
|
||||||
case Result::READ_ERR_AGAIN:
|
case Result::READ_ERR_AGAIN:
|
||||||
error("READ_ERR_AGAIN"); break;
|
error("READ_ERR_AGAIN"); break;
|
||||||
case Result::READ_ERR_WOULD_BLOCK:
|
case Result::READ_ERR_WOULD_BLOCK:
|
||||||
@ -470,7 +472,13 @@ void Component::construct(Genode::Env &env)
|
|||||||
Attached_rom_dataspace config_rom(env, "config");
|
Attached_rom_dataspace config_rom(env, "config");
|
||||||
Xml_node const config_xml = config_rom.xml();
|
Xml_node const config_xml = config_rom.xml();
|
||||||
|
|
||||||
|
struct Io_response_handler : Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
void handle_io_response() override { Genode::log(__func__, " called"); }
|
||||||
|
} io_response_handler;
|
||||||
|
|
||||||
Vfs::Dir_file_system vfs_root(env, heap, config_xml.sub_node("vfs"),
|
Vfs::Dir_file_system vfs_root(env, heap, config_xml.sub_node("vfs"),
|
||||||
|
io_response_handler,
|
||||||
Vfs::global_file_system_factory());
|
Vfs::global_file_system_factory());
|
||||||
char path[Vfs::MAX_PATH_LEN];
|
char path[Vfs::MAX_PATH_LEN];
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class Noux::Child_env
|
|||||||
try {
|
try {
|
||||||
binary_addr = local_rm.attach(binary_ds);
|
binary_addr = local_rm.attach(binary_ds);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
PWRN("could not attach dataspace");
|
warning("could not attach dataspace");
|
||||||
interpretable = false;
|
interpretable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,13 @@ struct Noux::Main
|
|||||||
/* initialize virtual file system */
|
/* initialize virtual file system */
|
||||||
Vfs::Global_file_system_factory &_fs_factory = Vfs::global_file_system_factory();
|
Vfs::Global_file_system_factory &_fs_factory = Vfs::global_file_system_factory();
|
||||||
|
|
||||||
|
struct Io_response_handler : Vfs::Io_response_handler
|
||||||
|
{
|
||||||
|
void handle_io_response() override { Genode::log(__func__, " called"); }
|
||||||
|
} _io_response_handler;
|
||||||
|
|
||||||
Vfs::Dir_file_system _root_dir { _env, _heap, _config.xml().sub_node("fstab"),
|
Vfs::Dir_file_system _root_dir { _env, _heap, _config.xml().sub_node("fstab"),
|
||||||
|
_io_response_handler,
|
||||||
_fs_factory };
|
_fs_factory };
|
||||||
|
|
||||||
Pid_allocator _pid_allocator;
|
Pid_allocator _pid_allocator;
|
||||||
|
@ -122,7 +122,7 @@ struct Noux::Vfs_io_channel : Io_channel
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
PWRN("invalid fcntl command %d", sysio.fcntl_in.cmd);
|
warning("invalid fcntl command ", (int)sysio.fcntl_in.cmd);
|
||||||
sysio.error.fcntl = Sysio::FCNTL_ERR_CMD_INVALID;
|
sysio.error.fcntl = Sysio::FCNTL_ERR_CMD_INVALID;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user