From 64a63885d10fd82798221c3237a00ea8602a3553 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 16 Jul 2018 16:41:55 +0200 Subject: [PATCH] VFS: line buffer LOG file-system Buffer data written to log file handles until newline or overflow. Ref #2467 Ref #2919 --- repos/libports/run/libc.run | 2 +- repos/libports/src/test/libc/main.cc | 11 +++++ repos/os/src/lib/vfs/log_file_system.h | 64 +++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/repos/libports/run/libc.run b/repos/libports/run/libc.run index 4da25a64a9..d58e43b472 100644 --- a/repos/libports/run/libc.run +++ b/repos/libports/run/libc.run @@ -22,7 +22,7 @@ install_config { - + diff --git a/repos/libports/src/test/libc/main.cc b/repos/libports/src/test/libc/main.cc index 81a548213c..c52bcebd5b 100644 --- a/repos/libports/src/test/libc/main.cc +++ b/repos/libports/src/test/libc/main.cc @@ -36,6 +36,15 @@ int main(int argc, char **argv) printf("Does printf work?\n"); printf("We can find out by printing a floating-point number: %f. How does that work?\n", 1.2345); + fprintf(stdout, "stdout: "); + for (int x = 0; x < 10; ++x) + fprintf(stdout, "%d ", x); + fprintf(stdout, "\n"); + + fprintf(stderr, "stderr: "); + for (int x = 0; x < 10; ++x) + fprintf(stderr, "%d ", x); + fprintf(stderr, "\n\n"); enum { ROUNDS = 64, SIZE_LARGE = 2048 }; @@ -137,5 +146,7 @@ int main(int argc, char **argv) } } + perror("perror"); + exit(error_count); } diff --git a/repos/os/src/lib/vfs/log_file_system.h b/repos/os/src/lib/vfs/log_file_system.h index 0fc1cd31d2..3e9eb18fc6 100644 --- a/repos/os/src/lib/vfs/log_file_system.h +++ b/repos/os/src/lib/vfs/log_file_system.h @@ -50,8 +50,32 @@ class Vfs::Log_file_system : public Single_file_system { private: + char _line_buf[Genode::Log_session::MAX_STRING_LEN]; + int _line_pos = 0; + Genode::Log_session &_log; + void _flush() + { + int strip = 0; + for (int i = _line_pos - 1; i > 0; --i) { + switch(_line_buf[i]) { + case '\n': + case '\t': + case ' ': + ++strip; + --_line_pos; + continue; + } + break; + } + + _line_buf[_line_pos > 0 ? _line_pos : 0] = '\0'; + + _log.write(_line_buf); + _line_pos = 0; + } + public: Log_vfs_handle(Directory_service &ds, @@ -61,6 +85,11 @@ class Vfs::Log_file_system : public Single_file_system : Single_vfs_handle(ds, fs, alloc, 0), _log(log) { } + ~Log_vfs_handle() + { + if (_line_pos > 0) _flush(); + } + Read_result read(char *, file_size, file_size &out_count) override { out_count = 0; @@ -74,11 +103,22 @@ class Vfs::Log_file_system : public Single_file_system /* count does not include the trailing '\0' */ while (count > 0) { - char tmp[Genode::Log_session::MAX_STRING_LEN]; - int const curr_count = min(count, sizeof(tmp) - 1); - memcpy(tmp, src, curr_count); - tmp[curr_count > 0 ? curr_count : 0] = 0; - _log.write(tmp); + int curr_count = min(count, ((sizeof(_line_buf) - 1) - _line_pos)); + + for (int i = 0; i < curr_count; ++i) { + if (src[i] == '\n') { + curr_count = i + 1; + break; + } + } + + memcpy(_line_buf + _line_pos, src, curr_count); + _line_pos += curr_count; + + if ((_line_pos == sizeof(_line_buf) - 1) || + (_line_buf[_line_pos - 1] == '\n')) + _flush(); + count -= curr_count; src += curr_count; } @@ -86,7 +126,13 @@ class Vfs::Log_file_system : public Single_file_system return WRITE_OK; } - bool read_ready() { return false; } + bool read_ready() override { return false; } + + void sync() + { + if (_line_pos > 0) + _flush(); + } }; public: @@ -121,6 +167,12 @@ class Vfs::Log_file_system : public Single_file_system catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; } catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; } } + + Sync_result complete_sync(Vfs_handle *vfs_handle) + { + static_cast(vfs_handle)->sync(); + return SYNC_OK; + } }; #endif /* _INCLUDE__VFS__LOG_FILE_SYSTEM_H_ */