watch mapped file for changes

This commit is contained in:
silverweed 2024-07-10 22:30:49 +02:00
parent 7816fda8c7
commit d714591dc1
6 changed files with 54 additions and 19 deletions

View file

@ -8,9 +8,9 @@ Size=1152,1414
[Window][main] [Window][main]
Pos=0,0 Pos=0,0
Size=1115,1414 Size=1115,470
[Window][Hex View] [Window][Hex View]
Pos=91,62 Pos=91,62
Size=1002,681 Size=986,681

View file

@ -49,6 +49,9 @@ struct App_State {
Window_Data win_data; Window_Data win_data;
User_Input user_input; User_Input user_input;
u8 *inspected_file; FILE *inspected_file;
u64 inspected_file_size; u8 *inspected_fmem;
u64 inspected_file_size;
// @Platform: inotify file descriptor
int inot;
}; };

View file

@ -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 internal
void monitor_key(GLFWwindow *window, u16 *key_state, i32 glfw_key, Input_Key haru_key) { void monitor_key(GLFWwindow *window, u16 *key_state, i32 glfw_key, Input_Key haru_key) {
u16& state = key_state[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_ImplGlfw_NewFrame();
ImGui::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 || if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS ||
glfwWindowShouldClose(window)) glfwWindowShouldClose(window))
{ {

View file

@ -12,18 +12,21 @@
#define asan_unpoison_memory_region(mem, cmt) #define asan_unpoison_memory_region(mem, cmt)
#endif #endif
// @Platform
internal internal
void *os_reserve(u64 size) void *os_reserve(u64 size)
{ {
return mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); return mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
} }
// @Platform
internal internal
void os_release(void *mem, u64 size) void os_release(void *mem, u64 size)
{ {
munmap(mem, size); munmap(mem, size);
} }
// @Platform
internal internal
b32x os_commit(void *addr, u64 size) b32x os_commit(void *addr, u64 size)
{ {

View file

@ -20,7 +20,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time)
char *text_buf = arena_push_array_no_zero<char>(scratch.arena, text_buf_size + 1); char *text_buf = arena_push_array_no_zero<char>(scratch.arena, text_buf_size + 1);
// TODO: convert file content to human readable // TODO: convert file content to human readable
for (u64 i = 0; i < text_buf_size / 2; ++i) 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; text_buf[text_buf_size] = 0;
if (ImGui::Begin("main")) { if (ImGui::Begin("main")) {
@ -28,7 +28,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time)
// ImGui::SetCursorX(30); // ImGui::SetCursorX(30);
// ImGui::TextWrapped("%s", text_buf); // ImGui::TextWrapped("%s", text_buf);
static MemoryEditor mem_edit = make_memory_editor(); 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(); ImGui::End();
} }
} }

View file

@ -6,8 +6,11 @@
#include <cstdint> #include <cstdint>
#include <chrono> #include <chrono>
// @Platform
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/inotify.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> // for NAME_MAX
#ifdef DEBUG #ifdef DEBUG
#include <sanitizer/asan_interface.h> #include <sanitizer/asan_interface.h>
@ -34,15 +37,6 @@ namespace chr = std::chrono;
using namespace ROOT::Experimental; 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 internal
b8 init_imgui(GLFWwindow* window) { b8 init_imgui(GLFWwindow* window) {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
@ -124,12 +118,13 @@ int main(int argc, char **argv)
return 1; return 1;
} }
// Open and map the file // Open and map te file
FILE *file = fopen(fname, "rb"); FILE *file = fopen(fname, "rb");
defer { fclose(file); }; defer { fclose(file); };
const int fd = fileno(file); int fd = fileno(file);
const size_t fsize = file_size(file); size_t fsize = file_size(file);
// @Platform
void *fmem = mmap(0, fsize, PROT_READ, MAP_SHARED_VALIDATE, fd, 0); void *fmem = mmap(0, fsize, PROT_READ, MAP_SHARED_VALIDATE, fd, 0);
if (!fmem) { if (!fmem) {
fprintf(stderr, "Failed to open file %s\n", fname); fprintf(stderr, "Failed to open file %s\n", fname);
@ -137,7 +132,21 @@ int main(int argc, char **argv)
} }
defer { munmap(fmem, fsize); }; 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 // Open the TFile
#if 0
TFile *tfile = TFile::Open(fname, "READ"); TFile *tfile = TFile::Open(fname, "READ");
if (!tfile) { if (!tfile) {
fprintf(stderr, "Failed to open TFile.\n"); 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); fprintf(stderr, "RNTuple '%s' not found in %s.\n", ntpl_name, fname);
return 1; return 1;
} }
#endif
// Start main loop // Start main loop
App_State app {}; App_State app {};
app.inspected_file = (u8*)fmem; app.inspected_file = file;
app.inspected_fmem = (u8*)fmem;
app.inspected_file_size = fsize; app.inspected_file_size = fsize;
app.inot = inot;
run_main_loop(window, arena, app); run_main_loop(window, arena, app);