diff --git a/repos/gems/recipes/pkg/test-fs_tool/runtime b/repos/gems/recipes/pkg/test-fs_tool/runtime
index 34278e5b03..c2616b0c89 100644
--- a/repos/gems/recipes/pkg/test-fs_tool/runtime
+++ b/repos/gems/recipes/pkg/test-fs_tool/runtime
@@ -11,6 +11,10 @@
[init -> report_rom] <listing>
[init -> report_rom] <dir path="/fs/items">
[init -> report_rom] <file name="1" writeable="yes">first</file>
+ [init -> report_rom] <file name="5" writeable="yes">fifth</file>
+ [init -> report_rom] </dir>
+ [init -> report_rom] <dir path="/fs/new/file/at/subdir">
+ [init -> report_rom] <file name="content" writeable="yes">new file</file>
[init -> report_rom] </dir>
[init -> report_rom] </listing>
@@ -81,6 +85,26 @@
+
+
+
+
+
+
+ fifth
+ new file
+
+
+
+
+
+
+
+
+
+
+
+
@@ -99,6 +123,7 @@
+
diff --git a/repos/gems/src/app/fs_tool/README b/repos/gems/src/app/fs_tool/README
index 5949470b8e..a421194a08 100644
--- a/repos/gems/src/app/fs_tool/README
+++ b/repos/gems/src/app/fs_tool/README
@@ -5,9 +5,17 @@ configured VFS. The file operations are given the configuration as follows:
!
! ...
!
+! Content to write to the file
!
!
The 'exit="yes"' attribute instructs the component to exit after completing
the sequence. Otherwise, the component keeps responding to configuration
changes by executing the operations found in the updated configurations.
+
+The operation creates the new file or overwrites the existing file
+given through the 'path' attribute with the content that is given inside the
+tag.
+
+The tag removes the existing file given through the 'path'
+attribute.
diff --git a/repos/gems/src/app/fs_tool/main.cc b/repos/gems/src/app/fs_tool/main.cc
index 3b5e07b903..7d952538d9 100644
--- a/repos/gems/src/app/fs_tool/main.cc
+++ b/repos/gems/src/app/fs_tool/main.cc
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
namespace Fs_tool {
using namespace Genode;
@@ -60,6 +61,8 @@ struct Fs_tool::Main
void _remove_file(Xml_node);
+ void _new_file(Xml_node);
+
void _handle_config()
{
_config.update();
@@ -71,9 +74,12 @@ struct Fs_tool::Main
_root_dir_fs.apply_config(config.sub_node("vfs"));
config.for_each_sub_node([&] (Xml_node operation) {
- if (operation.has_type("remove-file")) {
+
+ if (operation.has_type("remove-file"))
_remove_file(operation);
- }
+
+ if (operation.has_type("new-file"))
+ _new_file(operation);
});
if (config.attribute_value("exit", false)) {
@@ -115,5 +121,37 @@ void Fs_tool::Main::_remove_file(Xml_node operation)
}
+void Fs_tool::Main::_new_file(Xml_node operation)
+{
+ Path const path { operation.attribute_value("path", Path()) };
+
+ bool write_error = false;
+ bool create_error = false;
+
+ try {
+ New_file new_file(_root_dir, path);
+ auto write = [&] (char const *str)
+ {
+ if (new_file.append(str, strlen(str)) != New_file::Append_result::OK)
+ write_error = true;
+ };
+ Buffered_output<128, decltype(write)> output(write);
+
+ operation.with_raw_content([&] (char const *start, size_t size) {
+ print(output, Cstring(start, size)); });
+ }
+ catch (New_file::Create_failed) {
+ create_error = true; }
+
+ if (create_error && _verbose)
+ warning("operation "
+ "failed because creating the file failed");
+
+ if (write_error && _verbose)
+ warning("operation "
+ "failed because writing to the file failed");
+}
+
+
void Component::construct(Genode::Env &env) { static Fs_tool::Main main(env); }