2016-03-30 20:14:15 +02:00
|
|
|
/*
|
|
|
|
* \brief Internal nodes of VFS server
|
|
|
|
* \author Emery Hemingway
|
2017-02-01 21:07:14 +01:00
|
|
|
* \author Christian Helmuth
|
2016-03-30 20:14:15 +02:00
|
|
|
* \date 2016-03-29
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-01 21:07:14 +01:00
|
|
|
* Copyright (C) 2016-2017 Genode Labs GmbH
|
2016-03-30 20:14:15 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2016-03-30 20:14:15 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _VFS__NODE_H_
|
|
|
|
#define _VFS__NODE_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <file_system/node.h>
|
|
|
|
#include <vfs/file_system.h>
|
|
|
|
#include <os/path.h>
|
2017-01-04 15:27:42 +01:00
|
|
|
#include <base/id_space.h>
|
2016-03-30 20:14:15 +02:00
|
|
|
|
|
|
|
/* Local includes */
|
|
|
|
#include "assert.h"
|
|
|
|
|
|
|
|
namespace Vfs_server {
|
|
|
|
|
|
|
|
using namespace File_system;
|
|
|
|
using namespace Vfs;
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
class Node;
|
|
|
|
class Io_node;
|
|
|
|
class Watch_node;
|
|
|
|
class Directory;
|
|
|
|
class File;
|
|
|
|
class Symlink;
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-01-04 15:27:42 +01:00
|
|
|
typedef Genode::Id_space<Node> Node_space;
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
struct Session_io_handler : Interface
|
2017-02-01 21:07:14 +01:00
|
|
|
{
|
2018-03-31 16:50:49 +02:00
|
|
|
virtual void handle_node_io(Io_node &node) = 0;
|
|
|
|
virtual void handle_node_watch(Watch_node &node) = 0;
|
2017-02-01 21:07:14 +01:00
|
|
|
};
|
|
|
|
|
2017-02-12 10:58:27 +01:00
|
|
|
/**
|
|
|
|
* Read/write operation incomplete exception
|
|
|
|
*
|
|
|
|
* The operation can be retried later.
|
|
|
|
*/
|
|
|
|
struct Operation_incomplete { };
|
|
|
|
|
2016-03-30 20:14:15 +02:00
|
|
|
/* Vfs::MAX_PATH is shorter than File_system::MAX_PATH */
|
|
|
|
enum { MAX_PATH_LEN = Vfs::MAX_PATH_LEN };
|
|
|
|
|
|
|
|
typedef Genode::Path<MAX_PATH_LEN> Path;
|
|
|
|
|
|
|
|
typedef Genode::Allocator::Out_of_memory Out_of_memory;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type trait for determining the node type for a given handle type
|
|
|
|
*/
|
|
|
|
template<typename T> struct Node_type;
|
2018-03-31 16:50:49 +02:00
|
|
|
template<> struct Node_type<Node_handle> { typedef Io_node Type; };
|
|
|
|
template<> struct Node_type<Dir_handle> { typedef Directory Type; };
|
|
|
|
template<> struct Node_type<File_handle> { typedef File Type; };
|
|
|
|
template<> struct Node_type<Symlink_handle> { typedef Symlink Type; };
|
|
|
|
template<> struct Node_type<Watch_handle> { typedef Watch_node Type; };
|
2016-03-30 20:14:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Type trait for determining the handle type for a given node type
|
|
|
|
*/
|
|
|
|
template<typename T> struct Handle_type;
|
2018-03-31 16:50:49 +02:00
|
|
|
template<> struct Handle_type<Io_node> { typedef Node_handle Type; };
|
2016-03-30 20:14:15 +02:00
|
|
|
template<> struct Handle_type<Directory> { typedef Dir_handle Type; };
|
|
|
|
template<> struct Handle_type<File> { typedef File_handle Type; };
|
|
|
|
template<> struct Handle_type<Symlink> { typedef Symlink_handle Type; };
|
2018-03-31 16:50:49 +02:00
|
|
|
template<> struct Handle_type<Watch> { typedef Watch_handle Type; };
|
2016-03-30 20:14:15 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Note that the file objects are created at the
|
|
|
|
* VFS in the local node constructors, this is to
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
* ensure that Out_of_ram is thrown before
|
2016-03-30 20:14:15 +02:00
|
|
|
* the VFS is modified.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
class Vfs_server::Node : public File_system::Node_base,
|
2018-03-31 16:50:49 +02:00
|
|
|
private Node_space::Element
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2017-08-15 20:51:53 +02:00
|
|
|
public:
|
|
|
|
|
|
|
|
enum Op_state { IDLE, READ_QUEUED, SYNC_QUEUED };
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
/*
|
|
|
|
* Noncopyable
|
|
|
|
*/
|
|
|
|
Node(Node const &);
|
|
|
|
Node &operator = (Node const &);
|
|
|
|
|
|
|
|
Path const _path;
|
2018-03-31 16:50:49 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* I/O handler for session context
|
|
|
|
*/
|
|
|
|
Session_io_handler &_session_io_handler;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Node(Node_space &space, char const *node_path,
|
|
|
|
Session_io_handler &io_handler)
|
|
|
|
:
|
|
|
|
Node_space::Element(*this, space),
|
|
|
|
_path(node_path),
|
|
|
|
_session_io_handler(io_handler)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
virtual ~Node() { }
|
|
|
|
|
|
|
|
using Node_space::Element::id;
|
|
|
|
|
|
|
|
char const *path() const { return _path.base(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Print for debugging
|
|
|
|
*/
|
|
|
|
void print(Genode::Output &out) const {
|
|
|
|
out.out_string(_path.base()); }
|
|
|
|
};
|
|
|
|
|
|
|
|
class Vfs_server::Io_node : public Vfs_server::Node,
|
|
|
|
private Vfs::Vfs_handle::Context
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum Op_state { IDLE, READ_QUEUED, SYNC_QUEUED };
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Noncopyable
|
|
|
|
*/
|
|
|
|
Io_node(Io_node const &);
|
|
|
|
Io_node &operator = (Io_node const &);
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
Mode const _mode;
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
bool _notify_read_ready = false;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
Vfs::Vfs_handle::Context &context() { return *this; }
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
Vfs::Vfs_handle *_handle { nullptr };
|
|
|
|
Op_state op_state { Op_state::IDLE };
|
|
|
|
|
|
|
|
size_t _read(char *dst, size_t len, seek_off_t seek_offset)
|
|
|
|
{
|
|
|
|
_handle->seek(seek_offset);
|
|
|
|
|
|
|
|
typedef Vfs::File_io_service::Read_result Result;
|
|
|
|
|
|
|
|
Vfs::file_size out_count = 0;
|
|
|
|
Result out_result = Result::READ_OK;
|
|
|
|
|
|
|
|
switch (op_state) {
|
|
|
|
case Op_state::IDLE:
|
|
|
|
|
|
|
|
if (!_handle->fs().queue_read(_handle, len))
|
|
|
|
throw Operation_incomplete();
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case Op_state::READ_QUEUED:
|
|
|
|
out_result = _handle->fs().complete_read(_handle, dst, len,
|
|
|
|
out_count);
|
|
|
|
switch (out_result) {
|
|
|
|
case Result::READ_OK:
|
|
|
|
op_state = Op_state::IDLE;
|
|
|
|
return out_count;
|
|
|
|
|
|
|
|
case Result::READ_ERR_WOULD_BLOCK:
|
|
|
|
case Result::READ_ERR_AGAIN:
|
|
|
|
case Result::READ_ERR_INTERRUPT:
|
|
|
|
op_state = Op_state::IDLE;
|
|
|
|
throw Operation_incomplete();
|
|
|
|
|
|
|
|
case Result::READ_ERR_IO:
|
|
|
|
case Result::READ_ERR_INVALID:
|
|
|
|
op_state = Op_state::IDLE;
|
|
|
|
/* FIXME revise error handling */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case Result::READ_QUEUED:
|
|
|
|
op_state = Op_state::READ_QUEUED;
|
|
|
|
throw Operation_incomplete();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Op_state::SYNC_QUEUED:
|
|
|
|
throw Operation_incomplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
size_t _write(char const *src, size_t len,
|
|
|
|
seek_off_t seek_offset)
|
|
|
|
{
|
|
|
|
Vfs::file_size res = 0;
|
|
|
|
|
|
|
|
_handle->seek(seek_offset);
|
|
|
|
|
|
|
|
try {
|
|
|
|
_handle->fs().write(_handle, src, len, res);
|
|
|
|
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
|
|
throw Operation_incomplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
mark_as_updated();
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
Io_node(Node_space &space, char const *node_path, Mode node_mode,
|
|
|
|
Session_io_handler &io_handler)
|
|
|
|
: Node(space, node_path, io_handler), _mode(node_mode) { }
|
2017-08-15 20:51:53 +02:00
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
virtual ~Io_node() { }
|
2017-08-15 20:51:53 +02:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
using Node_space::Element::id;
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
static Io_node &node_by_context(Vfs::Vfs_handle::Context &context)
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
{
|
2018-03-31 16:50:49 +02:00
|
|
|
return static_cast<Io_node &>(context);
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
}
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
Mode mode() const { return _mode; }
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
virtual size_t read(char * /* dst */, size_t /* len */, seek_off_t)
|
2017-08-15 20:51:53 +02:00
|
|
|
{ return 0; }
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
virtual size_t write(char const * /* src */, size_t /* len */,
|
|
|
|
seek_off_t) { return 0; }
|
2017-08-15 20:51:53 +02:00
|
|
|
|
|
|
|
bool read_ready() { return _handle->fs().read_ready(_handle); }
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
/**
|
|
|
|
* The global handler has drawn an association from an I/O
|
|
|
|
* context and this open node, now process the event at the
|
|
|
|
* session for this node.
|
|
|
|
*/
|
|
|
|
void handle_io_response() {
|
|
|
|
_session_io_handler.handle_node_io(*this); }
|
2017-08-15 20:51:53 +02:00
|
|
|
|
|
|
|
void notify_read_ready(bool requested)
|
|
|
|
{
|
|
|
|
if (requested)
|
|
|
|
_handle->fs().notify_read_ready(_handle);
|
|
|
|
_notify_read_ready = requested;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool notify_read_ready() const { return _notify_read_ready; }
|
|
|
|
|
2018-07-23 19:53:09 +02:00
|
|
|
bool sync()
|
2017-08-15 20:51:53 +02:00
|
|
|
{
|
|
|
|
typedef Vfs::File_io_service::Sync_result Result;
|
|
|
|
Result out_result = Result::SYNC_OK;
|
|
|
|
|
|
|
|
switch (op_state) {
|
|
|
|
case Op_state::IDLE:
|
|
|
|
|
|
|
|
if (!_handle->fs().queue_sync(_handle))
|
|
|
|
throw Operation_incomplete();
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
/* fall through */
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
case Op_state::SYNC_QUEUED:
|
|
|
|
out_result = _handle->fs().complete_sync(_handle);
|
|
|
|
switch (out_result) {
|
|
|
|
case Result::SYNC_OK:
|
|
|
|
op_state = Op_state::IDLE;
|
2018-07-23 19:53:09 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case Result::SYNC_ERR_INVALID:
|
|
|
|
return false;
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
case Result::SYNC_QUEUED:
|
|
|
|
op_state = Op_state::SYNC_QUEUED;
|
|
|
|
throw Operation_incomplete();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Op_state::READ_QUEUED:
|
|
|
|
throw Operation_incomplete();
|
|
|
|
}
|
2018-07-23 19:53:09 +02:00
|
|
|
return false;
|
2017-08-15 20:51:53 +02:00
|
|
|
}
|
2016-03-30 20:14:15 +02:00
|
|
|
};
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
|
|
|
|
class Vfs_server::Watch_node final : public Vfs_server::Node,
|
|
|
|
private Vfs::Vfs_watch_handle::Context
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Noncopyable
|
|
|
|
*/
|
|
|
|
Watch_node(Watch_node const &);
|
|
|
|
Watch_node &operator = (Watch_node const &);
|
|
|
|
|
|
|
|
Vfs::Vfs_watch_handle &_watch_handle;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Watch_node(Node_space &space, char const *path,
|
|
|
|
Vfs::Vfs_watch_handle &handle,
|
|
|
|
Session_io_handler &io_handler)
|
|
|
|
:
|
|
|
|
Node(space, path, io_handler),
|
|
|
|
_watch_handle(handle)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* set the context so this Watch object
|
|
|
|
* is passed back thru the Io_handler
|
|
|
|
*/
|
|
|
|
_watch_handle.context(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
~Watch_node()
|
|
|
|
{
|
|
|
|
_watch_handle.context((Vfs::Vfs_watch_handle::Context*)~0ULL);
|
2018-04-23 09:25:51 +02:00
|
|
|
_watch_handle.close();
|
2018-03-31 16:50:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Watch_node &node_by_context(Vfs::Vfs_watch_handle::Context &context)
|
|
|
|
{
|
|
|
|
return static_cast<Watch_node &>(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The global handler has drawn an association from a watch
|
|
|
|
* context and this open node, now process the event at the
|
|
|
|
* session for this node.
|
|
|
|
*/
|
|
|
|
void handle_watch_response() {
|
|
|
|
_session_io_handler.handle_node_watch(*this); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Vfs_server::Symlink : Io_node
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2018-03-31 16:50:49 +02:00
|
|
|
Symlink(Node_space &space,
|
|
|
|
Vfs::File_system &vfs,
|
|
|
|
Genode::Allocator &alloc,
|
|
|
|
Session_io_handler &node_io_handler,
|
|
|
|
char const *link_path,
|
|
|
|
Mode mode,
|
|
|
|
bool create)
|
|
|
|
: Io_node(space, link_path, mode, node_io_handler)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2017-08-15 20:51:53 +02:00
|
|
|
assert_openlink(vfs.openlink(link_path, create, &_handle, alloc));
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
_handle->context = &context();
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2018-04-23 09:25:51 +02:00
|
|
|
~Symlink() { _handle->close(); }
|
2016-03-30 20:14:15 +02:00
|
|
|
|
|
|
|
/********************
|
|
|
|
** Node interface **
|
|
|
|
********************/
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
size_t read(char *dst, size_t len, seek_off_t seek_offset)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2017-08-15 20:51:53 +02:00
|
|
|
if (seek_offset != 0) {
|
|
|
|
/* partial read is not supported */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _read(dst, len, 0);
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2018-02-13 15:13:06 +01:00
|
|
|
size_t write(char const *src, size_t const len, seek_off_t)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2017-07-12 17:05:38 +02:00
|
|
|
/*
|
|
|
|
* if the symlink target is too long return a short result
|
|
|
|
* because a competent File_system client will error on a
|
|
|
|
* length mismatch
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (len > MAX_PATH_LEN) {
|
|
|
|
return len >> 1;
|
|
|
|
}
|
|
|
|
|
2016-03-30 20:14:15 +02:00
|
|
|
/* ensure symlink gets something null-terminated */
|
2017-07-12 17:05:38 +02:00
|
|
|
Genode::String<MAX_PATH_LEN+1> target(Genode::Cstring(src, len));
|
|
|
|
size_t const target_len = target.length()-1;
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
file_size out_count;
|
|
|
|
|
|
|
|
if (_handle->fs().write(_handle, target.string(), target_len, out_count) !=
|
|
|
|
File_io_service::WRITE_OK)
|
|
|
|
return 0;
|
2016-03-30 20:14:15 +02:00
|
|
|
|
|
|
|
mark_as_updated();
|
|
|
|
notify_listeners();
|
2018-02-13 15:13:06 +01:00
|
|
|
return len;
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
class Vfs_server::File : public Io_node
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
/*
|
|
|
|
* Noncopyable
|
|
|
|
*/
|
|
|
|
File(File const &);
|
|
|
|
File &operator = (File const &);
|
|
|
|
|
|
|
|
char const *_leaf_path = nullptr; /* offset pointer to Node::_path */
|
2017-02-12 10:58:27 +01:00
|
|
|
|
|
|
|
public:
|
2017-02-01 21:07:14 +01:00
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
File(Node_space &space,
|
|
|
|
Vfs::File_system &vfs,
|
|
|
|
Genode::Allocator &alloc,
|
|
|
|
Session_io_handler &node_io_handler,
|
|
|
|
char const *file_path,
|
|
|
|
Mode fs_mode,
|
|
|
|
bool create)
|
2017-02-01 21:07:14 +01:00
|
|
|
:
|
2018-03-31 16:50:49 +02:00
|
|
|
Io_node(space, file_path, fs_mode, node_io_handler)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
|
|
|
unsigned vfs_mode =
|
|
|
|
(fs_mode-1) | (create ? Vfs::Directory_service::OPEN_MODE_CREATE : 0);
|
|
|
|
|
2016-04-26 16:28:07 +02:00
|
|
|
assert_open(vfs.open(file_path, vfs_mode, &_handle, alloc));
|
2017-02-01 21:07:14 +01:00
|
|
|
_leaf_path = vfs.leaf_path(path());
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
_handle->context = &context();
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2018-04-23 09:25:51 +02:00
|
|
|
~File() { _handle->close(); }
|
2016-03-30 20:14:15 +02:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
if (seek_offset == (seek_off_t)SEEK_TAIL) {
|
2016-04-26 16:28:07 +02:00
|
|
|
typedef Directory_service::Stat_result Result;
|
|
|
|
Vfs::Directory_service::Stat st;
|
|
|
|
|
|
|
|
/* if stat fails, try and see if the VFS will seek to the end */
|
|
|
|
seek_offset = (_handle->ds().stat(_leaf_path, st) == Result::STAT_OK) ?
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
((len < st.size) ? (st.size - len) : 0) : (seek_off_t)SEEK_TAIL;
|
2016-04-26 16:28:07 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
return _read(dst, len, seek_offset);
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
size_t write(char const *src, size_t len,
|
2017-02-01 21:07:14 +01:00
|
|
|
seek_off_t seek_offset) override
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
if (seek_offset == (seek_off_t)SEEK_TAIL) {
|
2016-04-26 16:28:07 +02:00
|
|
|
typedef Directory_service::Stat_result Result;
|
|
|
|
Vfs::Directory_service::Stat st;
|
|
|
|
|
|
|
|
/* if stat fails, try and see if the VFS will seek to the end */
|
|
|
|
seek_offset = (_handle->ds().stat(_leaf_path, st) == Result::STAT_OK) ?
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
st.size : (seek_off_t)SEEK_TAIL;
|
2016-04-26 16:28:07 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
return _write(src, len, seek_offset);
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
2017-02-01 21:07:14 +01:00
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
void truncate(file_size_t size)
|
2017-02-01 21:07:14 +01:00
|
|
|
{
|
2017-08-15 20:51:53 +02:00
|
|
|
assert_truncate(_handle->fs().ftruncate(_handle, size));
|
|
|
|
mark_as_updated();
|
2017-02-01 21:07:14 +01:00
|
|
|
}
|
2016-03-30 20:14:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-03-31 16:50:49 +02:00
|
|
|
struct Vfs_server::Directory : Io_node
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2018-03-31 16:50:49 +02:00
|
|
|
Directory(Node_space &space,
|
|
|
|
Vfs::File_system &vfs,
|
|
|
|
Genode::Allocator &alloc,
|
|
|
|
Session_io_handler &node_io_handler,
|
|
|
|
char const *dir_path,
|
|
|
|
bool create)
|
|
|
|
: Io_node(space, dir_path, READ_ONLY, node_io_handler)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
2017-08-15 20:51:53 +02:00
|
|
|
assert_opendir(vfs.opendir(dir_path, create, &_handle, alloc));
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
_handle->context = &context();
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2018-04-23 09:25:51 +02:00
|
|
|
~Directory() { _handle->close(); }
|
2017-11-28 16:23:14 +01:00
|
|
|
|
2017-01-04 15:27:42 +01:00
|
|
|
Node_space::Id file(Node_space &space,
|
|
|
|
Vfs::File_system &vfs,
|
|
|
|
Genode::Allocator &alloc,
|
|
|
|
char const *file_path,
|
|
|
|
Mode mode,
|
|
|
|
bool create)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
|
|
|
Path subpath(file_path, path());
|
|
|
|
char const *path_str = subpath.base();
|
|
|
|
|
|
|
|
File *file;
|
2017-02-01 21:07:14 +01:00
|
|
|
try {
|
2018-03-31 16:50:49 +02:00
|
|
|
file = new (alloc) File(space, vfs, alloc,
|
|
|
|
_session_io_handler,
|
|
|
|
path_str, mode, create);
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
} catch (Out_of_memory) { throw Out_of_ram(); }
|
2017-02-01 21:07:14 +01:00
|
|
|
|
2016-03-30 20:14:15 +02:00
|
|
|
if (create)
|
|
|
|
mark_as_updated();
|
2017-01-04 15:27:42 +01:00
|
|
|
return file->id();
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
2017-01-04 15:27:42 +01:00
|
|
|
Node_space::Id symlink(Node_space &space,
|
|
|
|
Vfs::File_system &vfs,
|
|
|
|
Genode::Allocator &alloc,
|
|
|
|
char const *link_path,
|
|
|
|
Mode mode,
|
|
|
|
bool create)
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
|
|
|
Path subpath(link_path, path());
|
|
|
|
char const *path_str = subpath.base();
|
|
|
|
|
|
|
|
Symlink *link;
|
2018-03-31 16:50:49 +02:00
|
|
|
try { link = new (alloc) Symlink(space, vfs, alloc,
|
|
|
|
_session_io_handler,
|
2017-08-15 20:51:53 +02:00
|
|
|
path_str, mode, create); }
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
catch (Out_of_memory) { throw Out_of_ram(); }
|
2016-03-30 20:14:15 +02:00
|
|
|
if (create)
|
|
|
|
mark_as_updated();
|
2017-01-04 15:27:42 +01:00
|
|
|
return link->id();
|
2016-03-30 20:14:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************
|
|
|
|
** Node interface **
|
|
|
|
********************/
|
|
|
|
|
2017-08-15 20:51:53 +02:00
|
|
|
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
2016-03-30 20:14:15 +02:00
|
|
|
{
|
|
|
|
Directory_service::Dirent vfs_dirent;
|
|
|
|
size_t blocksize = sizeof(File_system::Directory_entry);
|
|
|
|
|
|
|
|
unsigned index = (seek_offset / blocksize);
|
|
|
|
|
|
|
|
size_t remains = len;
|
|
|
|
|
|
|
|
while (remains >= blocksize) {
|
2017-08-15 20:51:53 +02:00
|
|
|
|
|
|
|
if ((_read((char*)&vfs_dirent, sizeof(vfs_dirent),
|
|
|
|
index * sizeof(vfs_dirent)) < sizeof(vfs_dirent)) ||
|
|
|
|
(vfs_dirent.type == Vfs::Directory_service::DIRENT_TYPE_END))
|
2016-03-30 20:14:15 +02:00
|
|
|
return len - remains;
|
|
|
|
|
|
|
|
File_system::Directory_entry *fs_dirent = (Directory_entry *)dst;
|
|
|
|
fs_dirent->inode = vfs_dirent.fileno;
|
|
|
|
switch (vfs_dirent.type) {
|
|
|
|
case Vfs::Directory_service::DIRENT_TYPE_DIRECTORY:
|
|
|
|
fs_dirent->type = File_system::Directory_entry::TYPE_DIRECTORY;
|
|
|
|
break;
|
|
|
|
case Vfs::Directory_service::DIRENT_TYPE_SYMLINK:
|
|
|
|
fs_dirent->type = File_system::Directory_entry::TYPE_SYMLINK;
|
|
|
|
break;
|
|
|
|
case Vfs::Directory_service::DIRENT_TYPE_FILE:
|
|
|
|
default:
|
|
|
|
fs_dirent->type = File_system::Directory_entry::TYPE_FILE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
strncpy(fs_dirent->name, vfs_dirent.name, MAX_NAME_LEN);
|
|
|
|
|
|
|
|
remains -= blocksize;
|
|
|
|
dst += blocksize;
|
|
|
|
}
|
|
|
|
return len - remains;
|
|
|
|
}
|
2017-02-01 21:07:14 +01:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 15:42:15 +01:00
|
|
|
size_t write(char const *, size_t, seek_off_t) override { return 0; }
|
2016-03-30 20:14:15 +02:00
|
|
|
};
|
|
|
|
|
2016-05-25 22:11:09 +02:00
|
|
|
#endif /* _VFS__NODE_H_ */
|