diff --git a/ports/src/noux/dir_file_system.h b/ports/src/noux/dir_file_system.h index 81e0973fc1..7d69a477c0 100644 --- a/ports/src/noux/dir_file_system.h +++ b/ports/src/noux/dir_file_system.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace Noux { @@ -96,6 +98,18 @@ namespace Noux { continue; } + if (sub_node.has_type("null")) { + _append_file_system(new Null_file_system()); + + continue; + } + + if (sub_node.has_type("zero")) { + _append_file_system(new Zero_file_system()); + + continue; + } + { char type_name[64]; sub_node.type_name(type_name, sizeof(type_name)); diff --git a/ports/src/noux/null_file_system.h b/ports/src/noux/null_file_system.h new file mode 100644 index 0000000000..ef30b9b57b --- /dev/null +++ b/ports/src/noux/null_file_system.h @@ -0,0 +1,178 @@ +/* + * \brief null filesystem + * \author Josef Soentgen + * \date 2012-07-31 + */ + +/* + * Copyright (C) 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__NULL_FILE_SYSTEM_H_ +#define _NOUX__NULL_FILE_SYSTEM_H_ + +/* Genode includes */ +#include +#include + +/* Noux includes */ +#include +#include "file_system.h" + + +namespace Noux { + + class Null_file_system : public File_system + { + private: + + const char *_filename() { return "null"; } + + bool _is_root(const char *path) + { + return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0); + } + + bool _is_null_file(const char *path) + { + return (strlen(path) == (strlen(_filename()) + 1)) && + (strcmp(&path[1], _filename()) == 0); + } + + public: + + Null_file_system() { } + + + /********************************* + ** Directory-service interface ** + *********************************/ + + Dataspace_capability dataspace(char const *path) + { + /* not supported */ + return Dataspace_capability(); + } + + void release(char const *path, Dataspace_capability ds_cap) + { + /* not supported */ + } + + bool stat(Sysio *sysio, char const *path) + { + Sysio::Stat st = { 0, 0, 0, 0, 0, 0 }; + + if (_is_root(path)) + st.mode = Sysio::STAT_MODE_DIRECTORY; + else if (_is_null_file(path)) { + st.mode = Sysio::STAT_MODE_CHARDEV; + } else { + sysio->error.stat = Sysio::STAT_ERR_NO_ENTRY; + return false; + } + + sysio->stat_out.st = st; + return true; + } + + bool dirent(Sysio *sysio, char const *path, off_t index) + { + if (_is_root(path)) { + if (index == 0) { + sysio->dirent_out.entry.type = Sysio::DIRENT_TYPE_CHARDEV; + strncpy(sysio->dirent_out.entry.name, + _filename(), + sizeof(sysio->dirent_out.entry.name)); + } else { + sysio->dirent_out.entry.type = Sysio::DIRENT_TYPE_END; + } + + return true; + } + + return false; + } + + size_t num_dirent(char const *path) + { + if (_is_root(path)) + return 1; + else + return 0; + } + + bool is_directory(char const *path) + { + if (_is_root(path)) + return true; + + return false; + } + + char const *leaf_path(char const *path) + { + return path; + } + + Vfs_handle *open(Sysio *sysio, char const *path) + { + if (!_is_null_file(path)) { + sysio->error.open = Sysio::OPEN_ERR_UNACCESSIBLE; + return 0; + } + + return new (env()->heap()) Vfs_handle(this, this, 0); + } + + bool unlink(Sysio *sysio, char const *path) + { + /* not supported */ + return false; + } + + bool rename(Sysio *sysio, char const *from_path, char const *to_path) + { + /* not supported */ + return false; + } + + bool mkdir(Sysio *sysio, char const *path) + { + /* not supported */ + return false; + } + + /*************************** + ** File_system interface ** + ***************************/ + + char const *name() const { return "null"; } + + + /******************************** + ** File I/O service interface ** + ********************************/ + + bool write(Sysio *sysio, Vfs_handle *handle) + { + sysio->write_out.count = sysio->write_in.count; + + return true; + } + + bool read(Sysio *sysio, Vfs_handle *vfs_handle) + { + sysio->read_out.count = 0; + + return true; + } + + bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle) { return false; } + }; +} + +#endif /* _NOUX__NULL_FILE_SYSTEM_H_ */ diff --git a/ports/src/noux/zero_file_system.h b/ports/src/noux/zero_file_system.h new file mode 100644 index 0000000000..5979c10e4f --- /dev/null +++ b/ports/src/noux/zero_file_system.h @@ -0,0 +1,182 @@ +/* + * \brief zero filesystem + * \author Josef Soentgen + * \date 2012-07-31 + */ + +/* + * Copyright (C) 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__ZERO_FILE_SYSTEM_H_ +#define _NOUX__ZERO_FILE_SYSTEM_H_ + +/* Genode includes */ +#include +#include + +/* Noux includes */ +#include +#include "file_system.h" + + +namespace Noux { + + class Zero_file_system : public File_system + { + private: + + const char *_filename() { return "zero"; } + + bool _is_root(const char *path) + { + return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0); + } + + bool _is_device_zero_file(const char *path) + { + return (strlen(path) == (strlen(_filename()) + 1)) && + (strcmp(&path[1], _filename()) == 0); + } + + public: + + Zero_file_system() { } + + + /********************************* + ** Directory-service interface ** + *********************************/ + + Dataspace_capability dataspace(char const *path) + { + /* not supported */ + return Dataspace_capability(); + } + + void release(char const *path, Dataspace_capability ds_cap) + { + /* not supported */ + } + + bool stat(Sysio *sysio, char const *path) + { + Sysio::Stat st = { 0, 0, 0, 0, 0, 0 }; + + if (_is_root(path)) + st.mode = Sysio::STAT_MODE_DIRECTORY; + else if (_is_device_zero_file(path)) { + st.mode = Sysio::STAT_MODE_CHARDEV; + } else { + sysio->error.stat = Sysio::STAT_ERR_NO_ENTRY; + return false; + } + + sysio->stat_out.st = st; + return true; + } + + bool dirent(Sysio *sysio, char const *path, off_t index) + { + if (_is_root(path)) { + if (index == 0) { + sysio->dirent_out.entry.type = Sysio::DIRENT_TYPE_CHARDEV; + strncpy(sysio->dirent_out.entry.name, + _filename(), + sizeof(sysio->dirent_out.entry.name)); + } else { + sysio->dirent_out.entry.type = Sysio::DIRENT_TYPE_END; + } + + return true; + } + + return false; + } + + size_t num_dirent(char const *path) + { + if (_is_root(path)) + return 1; + else + return 0; + } + + bool is_directory(char const *path) + { + if (_is_root(path)) + return true; + + return false; + } + + char const *leaf_path(char const *path) + { + return path; + } + + Vfs_handle *open(Sysio *sysio, char const *path) + { + if (!_is_device_zero_file(path)) { + sysio->error.open = Sysio::OPEN_ERR_UNACCESSIBLE; + return 0; + } + + return new (env()->heap()) Vfs_handle(this, this, 0); + } + + bool unlink(Sysio *sysio, char const *path) + { + /* not supported */ + return false; + } + + bool rename(Sysio *sysio, char const *from_path, char const *to_path) + { + /* not supported */ + return false; + } + + bool mkdir(Sysio *sysio, char const *path) + { + /* not supported */ + return false; + } + + /*************************** + ** File_system interface ** + ***************************/ + + char const *name() const { return "zero"; } + + + /******************************** + ** File I/O service interface ** + ********************************/ + + bool write(Sysio *sysio, Vfs_handle *handle) + { + sysio->write_out.count = sysio->write_in.count; + + return true; + } + + bool read(Sysio *sysio, Vfs_handle *vfs_handle) + { + size_t nbytes = sysio->read_in.count; + + memset(sysio->read_out.chunk, 0, nbytes); + + sysio->read_out.count = nbytes; + + return true; + } + + bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle) { return false; } + }; +} + +#endif /* _NOUX__ZERO_FILE_SYSTEM_H_ */