genode/ports/src/noux/vfs_handle.h
Norman Feske 66290ea46d Stacked file systems for Noux
This patch introduces support for stacked file systems alongside new
glue for accessing file-system implementations provided via Genode's
new file-system-session interface.

Using stacked file systems, an arbitrary number of file systems (such
as tar archives or file systems implemented as separate Genode
components) can be composed to form one merged virtual file system.

An example is given via the 'ports/run/noux_bash.run' script. This run
script creates a virtual file system out of multiple tar archives each
containing the content of a particular GNU package. In addition, one
'ram_fs' is mounted, which enables Noux to perform write operations.
This way, the shell output can be redirected to a file, or files can
be saved in VIM.

Fixes #103.
2012-05-17 20:34:00 +02:00

106 lines
2.9 KiB
C++

/*
* \brief Representation of an open file
* \author Norman Feske
* \date 2011-02-17
*/
/*
* Copyright (C) 2011-2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _NOUX__VFS_HANDLE_H_
#define _NOUX__VFS_HANDLE_H_
/* Genode includes */
#include <base/printf.h>
/* Noux includes */
#include <file_io_service.h>
#include <directory_service.h>
namespace Noux {
class Sysio;
class Vfs_io_channel;
class Vfs_handle
{
private:
Directory_service *_ds;
File_io_service *_fs;
int _status_flags;
size_t _seek;
friend class Vfs_io_channel; /* for modifying '_seek' */
static Directory_service *_pseudo_directory_service()
{
struct Pseudo_directory_service : public Directory_service
{
static bool _msg(char const *sc) {
PERR("%s not supported by directory service", sc); return false; }
Dataspace_capability dataspace(char const *)
{
_msg("dataspace");
return Dataspace_capability();
}
void release(char const *, Dataspace_capability) { }
bool stat(Sysio *, char const *) { return _msg("stat"); }
Vfs_handle *open(Sysio *, char const *) { _msg("open"); return 0; }
bool dirent(Sysio *, char const *, off_t) { return _msg("dirent"); }
bool unlink(Sysio *, char const *) { return _msg("unlink"); }
bool rename(Sysio *, char const *, char const *) { return _msg("rename"); }
bool mkdir(Sysio *, char const *) { return _msg("mkdir"); }
size_t num_dirent(char const *) { return 0; }
bool is_directory(char const *) { return false; }
char const *leaf_path(char const *path) { return 0; }
};
static Pseudo_directory_service ds;
return &ds;
}
static File_io_service *_pseudo_file_io_service()
{
struct Pseudo_file_io_service : public File_io_service
{
static bool _msg(char const *sc) {
PERR("%s not supported by file system", sc); return false; }
bool write(Sysio *sysio, Vfs_handle *handle) { return _msg("write"); }
bool read(Sysio *sysio, Vfs_handle *handle) { return _msg("read"); }
};
static Pseudo_file_io_service fs;
return &fs;
}
public:
enum { STATUS_RDONLY = 0, STATUS_WRONLY = 1, STATUS_RDWR = 2 };
Vfs_handle(Directory_service *ds, File_io_service *fs, int status_flags)
:
_ds(ds ? ds : _pseudo_directory_service()),
_fs(fs ? fs : _pseudo_file_io_service()),
_status_flags(status_flags),
_seek(0)
{ }
Directory_service *ds() { return _ds; }
File_io_service *fs() { return _fs; }
int status_flags() { return _status_flags; }
size_t seek() const { return _seek; }
};
}
#endif /* _NOUX__VFS_HANDLE_H_ */