From d714591dc18dece66421e18c024387fca8fe003a Mon Sep 17 00:00:00 2001 From: silverweed Date: Wed, 10 Jul 2024 22:30:49 +0200 Subject: [PATCH] watch mapped file for changes --- imgui.ini | 4 ++-- src/app_state.h | 7 +++++-- src/mainloop.cpp | 17 +++++++++++++++++ src/mem.cpp | 3 +++ src/render.cpp | 4 ++-- src/rntviewer.cpp | 38 +++++++++++++++++++++++++------------- 6 files changed, 54 insertions(+), 19 deletions(-) diff --git a/imgui.ini b/imgui.ini index 4e35b70..d44e7d9 100644 --- a/imgui.ini +++ b/imgui.ini @@ -8,9 +8,9 @@ Size=1152,1414 [Window][main] Pos=0,0 -Size=1115,1414 +Size=1115,470 [Window][Hex View] Pos=91,62 -Size=1002,681 +Size=986,681 diff --git a/src/app_state.h b/src/app_state.h index ee0f81b..f2cfc70 100644 --- a/src/app_state.h +++ b/src/app_state.h @@ -49,6 +49,9 @@ struct App_State { Window_Data win_data; User_Input user_input; - u8 *inspected_file; - u64 inspected_file_size; + FILE *inspected_file; + u8 *inspected_fmem; + u64 inspected_file_size; + // @Platform: inotify file descriptor + int inot; }; diff --git a/src/mainloop.cpp b/src/mainloop.cpp index 82740f4..3805400 100644 --- a/src/mainloop.cpp +++ b/src/mainloop.cpp @@ -1,3 +1,12 @@ +internal +size_t file_size(FILE *f) +{ + fseek(f, 0, SEEK_END); + size_t res = ftell(f); + fseek(f, 0, SEEK_SET); + return res; +} + internal void monitor_key(GLFWwindow *window, u16 *key_state, i32 glfw_key, Input_Key haru_key) { u16& state = key_state[haru_key]; @@ -53,6 +62,14 @@ void run_main_loop(GLFWwindow *window, Arena *arena, App_State &app) ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + // Check if the inspected file changed + { + char buf[sizeof(inotify_event) + NAME_MAX + 1]; + ssize_t nbytes = read(app.inot, buf, sizeof(buf)); + if (nbytes) + app.inspected_file_size = file_size(app.inspected_file); + } + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) { diff --git a/src/mem.cpp b/src/mem.cpp index dee7dd9..1418cf1 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -12,18 +12,21 @@ #define asan_unpoison_memory_region(mem, cmt) #endif +// @Platform internal void *os_reserve(u64 size) { return mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); } +// @Platform internal void os_release(void *mem, u64 size) { munmap(mem, size); } +// @Platform internal b32x os_commit(void *addr, u64 size) { diff --git a/src/render.cpp b/src/render.cpp index 12ba078..f64336e 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -20,7 +20,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time) char *text_buf = arena_push_array_no_zero(scratch.arena, text_buf_size + 1); // TODO: convert file content to human readable for (u64 i = 0; i < text_buf_size / 2; ++i) - sprintf(&text_buf[2 * i], "%02X", app.inspected_file[i]); + sprintf(&text_buf[2 * i], "%02X", app.inspected_fmem[i]); text_buf[text_buf_size] = 0; if (ImGui::Begin("main")) { @@ -28,7 +28,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time) // ImGui::SetCursorX(30); // ImGui::TextWrapped("%s", text_buf); static MemoryEditor mem_edit = make_memory_editor(); - mem_edit.DrawWindow("Hex View", app.inspected_file, app.inspected_file_size); + mem_edit.DrawWindow("Hex View", app.inspected_fmem, app.inspected_file_size); ImGui::End(); } } diff --git a/src/rntviewer.cpp b/src/rntviewer.cpp index 5ba0651..0d46750 100644 --- a/src/rntviewer.cpp +++ b/src/rntviewer.cpp @@ -6,8 +6,11 @@ #include #include +// @Platform #include +#include #include +#include // for NAME_MAX #ifdef DEBUG #include @@ -34,15 +37,6 @@ namespace chr = std::chrono; using namespace ROOT::Experimental; -internal -size_t file_size(FILE *f) -{ - fseek(f, 0, SEEK_END); - size_t res = ftell(f); - fseek(f, 0, SEEK_SET); - return res; -} - internal b8 init_imgui(GLFWwindow* window) { IMGUI_CHECKVERSION(); @@ -124,12 +118,13 @@ int main(int argc, char **argv) return 1; } - // Open and map the file + // Open and map te file FILE *file = fopen(fname, "rb"); defer { fclose(file); }; - const int fd = fileno(file); - const size_t fsize = file_size(file); + int fd = fileno(file); + size_t fsize = file_size(file); + // @Platform void *fmem = mmap(0, fsize, PROT_READ, MAP_SHARED_VALIDATE, fd, 0); if (!fmem) { fprintf(stderr, "Failed to open file %s\n", fname); @@ -137,7 +132,21 @@ int main(int argc, char **argv) } defer { munmap(fmem, fsize); }; + // @Platform: watch file for changes (to adapt the displayed file size - otherwise + // we may try to access invalid memory when the file gets shrunk) + int inot = inotify_init1(IN_NONBLOCK); + if (inot == -1) { + fprintf(stderr, "Failed to init inotify: %s (%d)\n", strerror(errno), errno); + return 1; + } + if (inotify_add_watch(inot, fname, IN_MODIFY) == -1) { + fprintf(stderr, "Failed to add inotify watch: %s (%d)\n", strerror(errno), errno); + return 1; + } + defer { close(inot); }; + // Open the TFile +#if 0 TFile *tfile = TFile::Open(fname, "READ"); if (!tfile) { fprintf(stderr, "Failed to open TFile.\n"); @@ -151,11 +160,14 @@ int main(int argc, char **argv) fprintf(stderr, "RNTuple '%s' not found in %s.\n", ntpl_name, fname); return 1; } +#endif // Start main loop App_State app {}; - app.inspected_file = (u8*)fmem; + app.inspected_file = file; + app.inspected_fmem = (u8*)fmem; app.inspected_file_size = fsize; + app.inot = inot; run_main_loop(window, arena, app);