2024-07-11 14:00:43 +02:00
|
|
|
#include <sys/mman.h>
|
2024-07-12 09:53:01 +02:00
|
|
|
#include <errno.h>
|
2024-07-11 14:00:43 +02:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h> // for NAME_MAX
|
2024-08-21 13:56:30 +02:00
|
|
|
#if defined(R__LINUX)
|
|
|
|
#include <sys/inotify.h>
|
|
|
|
#endif
|
2024-07-11 14:00:43 +02:00
|
|
|
|
2024-07-17 13:20:46 +02:00
|
|
|
internal
|
|
|
|
i32 os_page_size()
|
|
|
|
{
|
2024-10-14 10:35:51 +02:00
|
|
|
return sysconf(_SC_PAGESIZE);
|
2024-07-17 13:20:46 +02:00
|
|
|
}
|
|
|
|
|
2024-07-11 14:00:43 +02:00
|
|
|
internal
|
2024-07-25 17:01:08 +02:00
|
|
|
bool os_open_and_map_file(String8 fname, App_State &app)
|
2024-07-11 14:00:43 +02:00
|
|
|
{
|
2024-07-25 17:01:08 +02:00
|
|
|
FILE *file = fopen(fname.c(), "rb");
|
2024-07-16 11:12:50 +02:00
|
|
|
if (!file) {
|
2024-07-25 17:01:08 +02:00
|
|
|
fprintf(stderr, "Failed to open file '%s' for reading: %s (%d)\n", fname.c(), strerror(errno), errno);
|
2024-07-16 11:12:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
2024-07-11 14:00:43 +02:00
|
|
|
int fd = fileno(file);
|
|
|
|
size_t fsize = file_size(file);
|
|
|
|
|
2024-08-21 13:56:30 +02:00
|
|
|
void *fmem = mmap(0, fsize, PROT_READ, MAP_SHARED, fd, 0);
|
2024-07-19 21:02:27 +02:00
|
|
|
if (!fmem) {
|
2024-07-25 17:01:08 +02:00
|
|
|
fprintf(stderr, "Failed to open file %s\n", fname.c());
|
2024-07-19 21:02:27 +02:00
|
|
|
return false;
|
|
|
|
}
|
2024-07-11 14:00:43 +02:00
|
|
|
|
2024-07-25 17:01:08 +02:00
|
|
|
app.inspected_file.name = fname;
|
2024-07-16 14:34:51 +02:00
|
|
|
app.inspected_file.stream = file;
|
|
|
|
app.inspected_file.size = fsize;
|
|
|
|
app.inspected_file.mem = reinterpret_cast<u8*>(fmem);
|
2024-07-16 11:12:50 +02:00
|
|
|
|
|
|
|
return true;
|
2024-07-11 14:00:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
void os_unmap_file(u8 *&mem, u64 size)
|
|
|
|
{
|
|
|
|
if (mem) munmap(mem, size);
|
|
|
|
mem = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
void *os_reserve(u64 size)
|
|
|
|
{
|
2024-07-17 13:20:46 +02:00
|
|
|
void *mem = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
|
|
|
if (UNLIKELY(mem == MAP_FAILED)) {
|
|
|
|
fprintf(stderr, "Error reserving memory: %s (%d)\n", strerror(errno), errno);
|
|
|
|
}
|
|
|
|
return mem;
|
2024-07-11 14:00:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
void os_release(void *mem, u64 size)
|
|
|
|
{
|
|
|
|
munmap(mem, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
b32x os_commit(void *addr, u64 size)
|
|
|
|
{
|
2024-07-17 13:20:46 +02:00
|
|
|
b32x err = mprotect(addr, size, PROT_READ|PROT_WRITE);
|
|
|
|
if (UNLIKELY(err)) {
|
|
|
|
fprintf(stderr, "Error committing memory: %s (%d)\n", strerror(errno), errno);
|
|
|
|
}
|
|
|
|
return err == 0;
|
2024-07-11 14:00:43 +02:00
|
|
|
}
|
|
|
|
|
2024-08-21 13:56:30 +02:00
|
|
|
#if defined(R__LINUX)
|
|
|
|
internal
|
|
|
|
void os_start_file_watch(String8 fname, App_State &app)
|
|
|
|
{
|
|
|
|
int inot = inotify_init1(IN_NONBLOCK);
|
|
|
|
if (inot == -1)
|
|
|
|
fprintf(stderr, "Failed to init inotify: %s (%d)\n", strerror(errno), errno);
|
|
|
|
if (inotify_add_watch(inot, fname.c(), IN_MODIFY) == -1)
|
|
|
|
fprintf(stderr, "Failed to add inotify watch: %s (%d)\n", strerror(errno), errno);
|
|
|
|
|
|
|
|
app.inspected_file.inot = inot;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
void os_stop_file_watch(App_State &app)
|
|
|
|
{
|
|
|
|
if (app.inspected_file.inot != -1) close(app.inspected_file.inot);
|
|
|
|
app.inspected_file.inot = -1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
internal
|
|
|
|
void os_start_file_watch(String8, App_State &)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Warning: file watch is not supported on this platform.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
|
|
|
void os_stop_file_watch(App_State &)
|
|
|
|
{}
|
|
|
|
#endif
|