diff --git a/repos/dde_rump/src/lib/rump/io.cc b/repos/dde_rump/src/lib/rump/io.cc index 22b4bfde64..952b04260d 100644 --- a/repos/dde_rump/src/lib/rump/io.cc +++ b/repos/dde_rump/src/lib/rump/io.cc @@ -314,7 +314,7 @@ void rumpuser_bio(int fd, int op, void *data, size_t dlen, int64_t off, Packet *p = backend()->alloc(); if (verbose) - PDBG("fd: %d op: %d len: %zu off: %lx p %p bio %p sync %u", fd, op, dlen, off, + PDBG("fd: %d op: %d len: %zu off: %lx p %p bio %p sync %u", fd, op, dlen, (unsigned long)off, p, donearg, !!(op & RUMPUSER_BIO_SYNC)); p->opcode= op & RUMPUSER_BIO_WRITE ? Block::Packet_descriptor::WRITE : diff --git a/repos/libports/src/server/ffat_fs/util.h b/repos/libports/src/server/ffat_fs/util.h index f7988b10e3..d28ad4f0b6 100644 --- a/repos/libports/src/server/ffat_fs/util.h +++ b/repos/libports/src/server/ffat_fs/util.h @@ -10,6 +10,7 @@ /* Genode includes */ #include +#include /** @@ -40,18 +41,6 @@ static inline bool is_basename(char const *path) } -/** - * Return true if character 'c' occurs in null-terminated string 'str' - */ -static inline bool string_contains(char const *str, char c) -{ - for (; *str; str++) - if (*str == c) - return true; - return false; -} - - /** * Return true if null-terminated string 'substr' occurs in null-terminated * string 'str' @@ -85,9 +74,9 @@ static inline bool valid_filename(char const *str) if (str[0] == 0) return false; /* must not contain '/' or '\' or ':' */ - if (string_contains(str, '/') || - string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '/') || + File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; return true; @@ -105,8 +94,8 @@ static inline bool valid_path(char const *str) return false; /* must not contain '\' or ':' */ - if (string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; /* must not contain "/../" */ diff --git a/repos/libports/src/server/fuse_fs/util.h b/repos/libports/src/server/fuse_fs/util.h index f7988b10e3..d28ad4f0b6 100644 --- a/repos/libports/src/server/fuse_fs/util.h +++ b/repos/libports/src/server/fuse_fs/util.h @@ -10,6 +10,7 @@ /* Genode includes */ #include +#include /** @@ -40,18 +41,6 @@ static inline bool is_basename(char const *path) } -/** - * Return true if character 'c' occurs in null-terminated string 'str' - */ -static inline bool string_contains(char const *str, char c) -{ - for (; *str; str++) - if (*str == c) - return true; - return false; -} - - /** * Return true if null-terminated string 'substr' occurs in null-terminated * string 'str' @@ -85,9 +74,9 @@ static inline bool valid_filename(char const *str) if (str[0] == 0) return false; /* must not contain '/' or '\' or ':' */ - if (string_contains(str, '/') || - string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '/') || + File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; return true; @@ -105,8 +94,8 @@ static inline bool valid_path(char const *str) return false; /* must not contain '\' or ':' */ - if (string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; /* must not contain "/../" */ diff --git a/repos/os/include/file_system/util.h b/repos/os/include/file_system/util.h index b8474c88ec..f16562818a 100644 --- a/repos/os/include/file_system/util.h +++ b/repos/os/include/file_system/util.h @@ -7,57 +7,237 @@ #ifndef _FILE_SYSTEM__UTIL_H_ #define _FILE_SYSTEM__UTIL_H_ -/** - * Return base-name portion of null-terminated path string - */ -static inline char const *basename(char const *path) -{ - char const *start = path; +#include +#include - for (; *path; path++) - if (*path == '/') - start = path + 1; +namespace File_system { - return start; -} + /** + * Return true if character 'c' occurs in null-terminated string 'str' + */ + inline bool string_contains(char const *str, char c) + { + for (; *str; str++) + if (*str == c) + return true; + return false; + } + + /** + * Return base-name portion of null-terminated path string + */ + static inline char const *basename(char const *path) + { + char const *start = path; + + for (; *path; path++) + if (*path == '/') + start = path + 1; + + return start; + } -/** - * Return true if specified path is a base name (contains no path delimiters) - */ -static inline bool is_basename(char const *path) -{ - for (; *path; path++) - if (*path == '/') - return false; + /** + * Return true if specified path is a base name (contains no path delimiters) + */ + static inline bool is_basename(char const *path) + { + for (; *path; path++) + if (*path == '/') + return false; - return true; -} + return true; + } -/** - * Return true if character 'c' occurs in null-terminated string 'str' - */ -static inline bool string_contains(char const *str, char c) -{ - for (; *str; str++) - if (*str == c) - return true; - return false; -} + /** + * Return true if 'str' is a valid node name + */ + static inline bool valid_name(char const *str) + { + if (string_contains(str, '/')) return false; + + /* must have at least one character */ + if (str[0] == 0) return false; + + return true; + } -/** - * Return true if 'str' is a valid node name - */ -static inline bool valid_name(char const *str) -{ - if (string_contains(str, '/')) return false; + /** + * Open a directory, ensuring all parent directories exists. + */ + static inline Dir_handle ensure_dir(Session &fs, char const *path) + { + try { + return fs.dir(path, false); + } catch (Lookup_failed) { + try { + return fs.dir(path, true); + } catch (Lookup_failed) { + Genode::Path target(path); + target.strip_last_element(); + target.remove_trailing('/'); + fs.close(ensure_dir(fs, target.base())); + } + } + return fs.dir(path, true); + } - /* must have at least one character */ - if (str[0] == 0) return false; - return true; + /** + * Collect pending packet acknowledgements, freeing the space occupied + * by the packet in the bulk buffer + * + * This function should be called prior enqueing new packets into the + * packet stream to free up space in the bulk buffer. + */ + static void collect_acknowledgements(Session::Tx::Source &source) + { + while (source.ack_avail()) + source.release_packet(source.get_acked_packet()); + } + + + /** + * Read file content + */ + static inline size_t read(Session &fs, File_handle const &file_handle, + void *dst, size_t count, seek_off_t seek_offset = 0) + { + bool success = true; + Session::Tx::Source &source = *fs.tx(); + + size_t const max_packet_size = source.bulk_buffer_size() / 2; + + size_t remaining_count = count; + + while (remaining_count && success) { + + collect_acknowledgements(source); + + size_t const curr_packet_size = min(remaining_count, max_packet_size); + + Packet_descriptor + packet(source.alloc_packet(curr_packet_size), + 0, + file_handle, + File_system::Packet_descriptor::READ, + curr_packet_size, + seek_offset); + + /* pass packet to server side */ + source.submit_packet(packet); + + packet = source.get_acked_packet(); + success = packet.succeeded(); + + size_t const read_num_bytes = min(packet.length(), curr_packet_size); + + /* copy-out payload into destination buffer */ + memcpy(dst, source.packet_content(packet), read_num_bytes); + + source.release_packet(packet); + + /* prepare next iteration */ + seek_offset += read_num_bytes; + dst = (void *)((Genode::addr_t)dst + read_num_bytes); + remaining_count -= read_num_bytes; + + /* + * If we received less bytes than requested, we reached the end + * of the file. + */ + if (read_num_bytes < curr_packet_size) + break; + } + + return count - remaining_count; + } + + + /** + * Write file content + */ + static inline size_t write(Session &fs, File_handle const &file_handle, + void const *src, size_t count, seek_off_t seek_offset = 0) + { + bool success = true; + Session::Tx::Source &source = *fs.tx(); + + size_t const max_packet_size = source.bulk_buffer_size() / 2; + + size_t remaining_count = count; + + while (remaining_count && success) { + + collect_acknowledgements(source); + + size_t const curr_packet_size = min(remaining_count, max_packet_size); + + Packet_descriptor + packet(source.alloc_packet(curr_packet_size), + 0, + file_handle, + File_system::Packet_descriptor::WRITE, + curr_packet_size, + seek_offset); + + /* copy-out source buffer into payload */ + memcpy(source.packet_content(packet), src, curr_packet_size); + + /* pass packet to server side */ + source.submit_packet(packet); + + packet = source.get_acked_packet();; + success = packet.succeeded(); + source.release_packet(packet); + + /* prepare next iteration */ + seek_offset += curr_packet_size; + src = (void *)((Genode::addr_t)src + curr_packet_size); + remaining_count -= curr_packet_size; + } + + return count - remaining_count; + } + + + class Handle_guard + { + private: + + Session &_session; + Node_handle _handle; + + public: + + Handle_guard(Session &session, Node_handle handle) + : _session(session), _handle(handle) { } + + ~Handle_guard() { _session.close(_handle); } + }; + + class Packet_guard + { + private: + + Session::Tx::Source &_source; + File_system::Packet_descriptor _packet; + + public: + + Packet_guard(Session::Tx::Source &source, + File_system::Packet_descriptor packet) + : _source(source), _packet(packet) { } + + ~Packet_guard() + { + _source.release_packet(_packet); + } + }; + } #endif /* _FILE_SYSTEM__UTIL_H_ */ diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index 1ed6623cb9..1112fddfa5 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -82,6 +82,10 @@ struct File_system::Node_handle Node_handle(int v) : value(v) { } bool valid() const { return value != -1; } + + bool operator == (Node_handle const &other) const { return other.value == value; } + bool operator != (Node_handle const &other) const { return other.value != value; } + }; diff --git a/repos/os/src/server/fs_rom/main.cc b/repos/os/src/server/fs_rom/main.cc index 74f740ca79..389ad3d8cd 100755 --- a/repos/os/src/server/fs_rom/main.cc +++ b/repos/os/src/server/fs_rom/main.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,104 +24,6 @@ #include -/********************************************* - ** Utilities for accessing the file system ** - *********************************************/ - -/* - * XXX The following generic utilities should be moved to a public place. - * They are based on those found in the 'libc_fs' plugin. We should - * unify them. - */ - -namespace File_system { - - /** - * Collect pending packet acknowledgements, freeing the space occupied - * by the packet in the bulk buffer - * - * This function should be called prior enqueing new packets into the - * packet stream to free up space in the bulk buffer. - */ - static void collect_acknowledgements(Session::Tx::Source &source) - { - while (source.ack_avail()) - source.release_packet(source.get_acked_packet()); - } - - - /** - * Read file content - */ - static inline size_t read(Session &fs, File_handle const &file_handle, - void *dst, size_t count, off_t seek_offset = 0) - { - Session::Tx::Source &source = *fs.tx(); - - size_t const max_packet_size = source.bulk_buffer_size() / 2; - - size_t remaining_count = count; - - while (remaining_count) { - - collect_acknowledgements(source); - - size_t const curr_packet_size = min(remaining_count, max_packet_size); - - Packet_descriptor - packet(source.alloc_packet(curr_packet_size), - 0, - file_handle, - File_system::Packet_descriptor::READ, - curr_packet_size, - seek_offset); - - /* pass packet to server side */ - source.submit_packet(packet); - - packet = source.get_acked_packet(); - - size_t const read_num_bytes = min(packet.length(), curr_packet_size); - - /* copy-out payload into destination buffer */ - memcpy(dst, source.packet_content(packet), read_num_bytes); - - source.release_packet(packet); - - /* prepare next iteration */ - seek_offset += read_num_bytes; - dst = (void *)((Genode::addr_t)dst + read_num_bytes); - remaining_count -= read_num_bytes; - - /* - * If we received less bytes than requested, we reached the end - * of the file. - */ - if (read_num_bytes < curr_packet_size) - break; - } - - return count - remaining_count; - } - - - struct Handle_guard - { - private: - - Session &_session; - Node_handle _handle; - - public: - - Handle_guard(Session &session, Node_handle handle) - : _session(session), _handle(handle) { } - - ~Handle_guard() { _session.close(_handle); } - }; -} - - /***************** ** ROM service ** *****************/ diff --git a/repos/os/src/server/tar_fs/util.h b/repos/os/src/server/tar_fs/util.h index 3cfcb1eb55..9eae76e78e 100644 --- a/repos/os/src/server/tar_fs/util.h +++ b/repos/os/src/server/tar_fs/util.h @@ -17,18 +17,7 @@ /* Genode includes */ #include - - -/** - * Return true if character 'c' occurs in null-terminated string 'str' - */ -static inline bool string_contains(char const *str, char c) -{ - for (; *str; str++) - if (*str == c) - return true; - return false; -} +#include /** @@ -64,9 +53,9 @@ static inline bool valid_filename(char const *str) if (str[0] == 0) return false; /* must not contain '/' or '\' or ':' */ - if (string_contains(str, '/') || - string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '/') || + File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; return true; @@ -85,8 +74,8 @@ static inline bool valid_path(char const *str) return false; /* must not contain '\' or ':' */ - if (string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; /* must not contain "/../" */ diff --git a/repos/os/src/server/trace_fs/main.cc b/repos/os/src/server/trace_fs/main.cc index 854a42d5f0..eed11e9bbe 100644 --- a/repos/os/src/server/trace_fs/main.cc +++ b/repos/os/src/server/trace_fs/main.cc @@ -25,6 +25,7 @@ #include #include #include +#include /* local includes */ #include @@ -47,9 +48,9 @@ static inline bool valid_filename(char const *str) if (str[0] == 0) return false; /* must not contain '/' or '\' or ':' */ - if (string_contains(str, '/') || - string_contains(str, '\\') || - string_contains(str, ':')) + if (File_system::string_contains(str, '/') || + File_system::string_contains(str, '\\') || + File_system::string_contains(str, ':')) return false; return true;