Commit: 516e168e738276ff2ab6dcba7472f7a6247b594a
Parent: 477fc2e932cd6ad0f0cc26b8af380ebd1120c52a
Author: Randy Palamar
Date: Fri, 29 Nov 2024 06:54:07 -0700
remove stat.h include
Diffstat:
7 files changed, 113 insertions(+), 142 deletions(-)
diff --git a/os_unix.c b/os_unix.c
@@ -4,16 +4,10 @@
#include <pwd.h>
#include <sys/mman.h>
#include <sys/select.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
-typedef struct {
- iptr handle;
- iptr process_id;
-} posix_platform_process;
-
#define OS_MAP_READ PROT_READ
#define OS_MAP_PRIVATE MAP_PRIVATE
@@ -26,17 +20,6 @@ os_get_time(void)
return result;
}
-static PLATFORM_GET_FILESTATS_FN(posix_get_file_stats)
-{
- struct stat sb = {0};
- FileStats result = {0};
- if (stat((c8 *)path, &sb) == 0) {
- result.size = sb.st_size;
- result.timestamp = sb.st_mtim.tv_sec * 1e9 + sb.st_mtim.tv_nsec;
- }
- return result;
-}
-
static u32
os_file_attribute_to_mode(u32 attr)
{
@@ -94,19 +77,21 @@ static PLATFORM_READ_FN(posix_read)
static PLATFORM_READ_FILE_FN(posix_read_file)
{
- i32 fd = open((c8 *)path, O_RDONLY);
- buffer->errors |= fd < 0;
+ s8 result = {0};
- if (!buffer->errors) {
- s8 text = {.len = buffer->cap - buffer->widx, .data = buffer->buf + buffer->widx};
- size rlen = posix_read(fd, text, 0);
+ stat_buffer sb;
+ i64 status = syscall2(SYS_stat, (iptr)path, (iptr)sb);
+ i32 fd = open((c8 *)path, O_RDONLY);
+
+ if (fd > 0 && status == 0) {
+ result = s8alloc(a, STAT_FILE_SIZE(sb));
+ size rlen = posix_read(fd, result, 0);
close(fd);
- buffer->errors |= text.len != rlen;
- if (!buffer->errors)
- buffer->widx += rlen;
+ if (result.len != rlen)
+ result.len = 0;
}
- return !buffer->errors;
+ return result;
}
static os_mapped_file
@@ -120,13 +105,14 @@ os_map_file(char *path, i32 mode, i32 perm)
default: ASSERT(0);
}
- i32 fd = open(path, open_mode);
- FileStats fs = posix_get_file_stats((u8 *)path);
+ stat_buffer sb;
+ i64 status = syscall2(SYS_stat, (iptr)path, (iptr)sb);
+ i32 fd = open(path, open_mode);
- if (fd != -1) {
- res.data = mmap(NULL, fs.size, mode, perm, fd, 0);
+ if (fd != -1 && status == 0) {
+ res.data = mmap(NULL, STAT_FILE_SIZE(sb), mode, perm, fd, 0);
if (res.data != MAP_FAILED)
- res.len = fs.size;
+ res.len = STAT_FILE_SIZE(sb);
close(fd);
}
@@ -199,7 +185,7 @@ execsh(char *defcmd)
_exit(1);
}
-static posix_platform_process
+static linux_platform_process
os_fork_child(char *cmd)
{
i32 cfd;
@@ -222,7 +208,7 @@ os_fork_child(char *cmd)
if (fcntl(cfd, F_SETFL, flags | O_NONBLOCK) == -1)
os_fatal(s8("os_fork_child: fcntl: F_SETFL\n"));
- return (posix_platform_process){.process_id = pid, .handle = cfd};
+ return (linux_platform_process){.process_id = pid, .handle = cfd};
}
static b32
diff --git a/platform_linux_amd64.c b/platform_linux_amd64.c
@@ -22,16 +22,15 @@
#define PAGE_SIZE 4096
-#define STAT_BUF_SIZE 144
-#define STAT_SIZE_OFF 48
+typedef __attribute__((aligned(16))) u8 stat_buffer[144];
+#define STAT_BUF_MEMBER(sb, t, off) (*(t *)((u8 *)(sb) + off))
+#define STAT_INODE(sb) STAT_BUF_MEMBER(sb, i64, 8)
+#define STAT_FILE_SIZE(sb) STAT_BUF_MEMBER(sb, i64, 48)
#define DIRENT_RECLEN_OFF 16
#define DIRENT_TYPE_OFF 18
#define DIRENT_NAME_OFF 19
-typedef signed long i64;
-typedef unsigned long u64;
-
static i64
syscall1(i64 n, i64 a1)
{
diff --git a/platform_linux_common.c b/platform_linux_common.c
@@ -30,6 +30,35 @@ typedef struct {
i32 handle;
} linux_file_watch;
+typedef struct {
+ iptr handle;
+ iptr process_id;
+} linux_platform_process;
+
+typedef struct {
+ Arena platform_memory;
+ void *window;
+
+ TerminalMemory memory;
+ TerminalInput input;
+
+ Stream char_stream;
+
+ linux_platform_process child;
+ i32 inotify_fd;
+ i32 win_fd;
+
+ linux_file_watch file_watches[32];
+ i32 file_watch_count;
+
+ Stream error_stream;
+
+#ifdef _DEBUG
+ void *library_handle;
+#endif
+} PlatformCtx;
+static PlatformCtx linux_ctx;
+
#include <sys/inotify.h>
#define LINUX_INOTIFY_MASK (IN_CLOSE|IN_MODIFY)
@@ -97,4 +126,58 @@ usage(char *argv0, Stream *err)
os_fatal(stream_to_s8(err));
}
+static PLATFORM_ADD_FILE_WATCH_FN(linux_add_file_watch)
+{
+ stat_buffer sb;
+ syscall2(SYS_stat, (iptr)path, (iptr)sb);
+
+ i32 wd = inotify_add_watch(linux_ctx.inotify_fd, (c8 *)path, LINUX_INOTIFY_MASK);
+ i32 idx = linux_ctx.file_watch_count++;
+ ASSERT(idx < ARRAY_COUNT(linux_ctx.file_watches));
+
+ linux_ctx.file_watches[idx].fn = fn;
+ linux_ctx.file_watches[idx].path = path;
+ linux_ctx.file_watches[idx].handle = wd;
+ linux_ctx.file_watches[idx].inode = STAT_INODE(sb);
+ linux_ctx.file_watches[idx].user_ctx = user_ctx;
+}
+
+static void
+dispatch_file_watch_events(PlatformCtx *ctx)
+{
+ u8 *mem = alloc_(&ctx->platform_memory, 4096, 64, 1);
+ s8 buf = {.len = 4096, .data = mem};
+ for (;;) {
+ size rlen = syscall3(SYS_read, ctx->inotify_fd, (iptr)buf.data, buf.len);
+ if (rlen <= 0)
+ break;
+ struct inotify_event *ie;
+ for (u8 *data = buf.data; data < buf.data + rlen; data += sizeof(*ie) + ie->len) {
+ ie = (struct inotify_event *)data;
+ for (i32 i = 0; i < ctx->file_watch_count; i++) {
+ linux_file_watch *fw = ctx->file_watches + i;
+ if (fw->handle == ie->wd) {
+ b32 file_changed = (ie->mask & IN_CLOSE_WRITE) != 0;
+ file_changed |= (ie->mask & IN_MODIFY) != 0;
+ /* NOTE: some editors and the compiler will rewrite a file
+ * completely and thus the inode will change; here we
+ * detect that and restart the watch */
+ stat_buffer sb;
+ syscall2(SYS_stat, (iptr)fw->path, (iptr)sb);
+ if (fw->inode != STAT_INODE(sb)) {
+ inotify_rm_watch(ctx->inotify_fd, fw->handle);
+ fw->inode = STAT_INODE(sb);
+ fw->handle = inotify_add_watch(ctx->inotify_fd,
+ (c8 *)fw->path,
+ LINUX_INOTIFY_MASK);
+ file_changed = 1;
+ }
+ if (file_changed)
+ fw->fn(fw->path, fw->user_ctx);
+ }
+ }
+ }
+ }
+}
+
#include "os_unix.c"
diff --git a/platform_linux_x11.c b/platform_linux_x11.c
@@ -17,31 +17,6 @@ typedef void *Window;
i32 XConnectionNumber(void *display);
i32 XPending(void *display);
-typedef struct {
- Arena platform_memory;
- void *window;
-
- TerminalMemory memory;
- TerminalInput input;
-
- Stream char_stream;
-
- posix_platform_process child;
- i32 inotify_fd;
- i32 x_fd;
-
- linux_file_watch file_watches[32];
- i32 file_watch_count;
-
- Stream error_stream;
-
-#ifdef _DEBUG
- void *library_handle;
-#endif
-} PlatformCtx;
-
-static PlatformCtx linux_ctx;
-
#ifndef _DEBUG
#define do_debug(...)
#include "vtgl.c"
@@ -260,50 +235,12 @@ init_window(PlatformCtx *ctx, iv2 window_size)
glfwSetWindowFocusCallback(window, focus_callback);
glfwSetWindowRefreshCallback(window, refresh_callback);
- ctx->x_fd = XConnectionNumber(glfwGetX11Display());
+ ctx->win_fd = XConnectionNumber(glfwGetX11Display());
return window;
}
static void
-dispatch_file_watch_events(PlatformCtx *ctx)
-{
- u8 *mem = alloc_(&ctx->platform_memory, 4096, 64, 1);
- s8 buf = {.len = 4096, .data = mem};
- for (;;) {
- size rlen = read(ctx->inotify_fd, buf.data, buf.len);
- if (rlen <= 0)
- break;
- struct inotify_event *ie;
- for (u8 *data = buf.data; data < buf.data + rlen; data += sizeof(*ie) + ie->len) {
- ie = (struct inotify_event *)data;
- for (i32 i = 0; i < ctx->file_watch_count; i++) {
- linux_file_watch *fw = ctx->file_watches + i;
- if (fw->handle == ie->wd) {
- b32 file_changed = (ie->mask & IN_CLOSE_WRITE) != 0;
- file_changed |= (ie->mask & IN_MODIFY) != 0;
- /* NOTE: some editors and the compiler will rewrite a file
- * completely and thus the inode will change; here we
- * detect that and restart the watch */
- struct stat sb;
- stat((c8 *)fw->path, &sb);
- if (fw->inode != sb.st_ino) {
- inotify_rm_watch(ctx->inotify_fd, fw->handle);
- fw->inode = sb.st_ino;
- fw->handle = inotify_add_watch(ctx->inotify_fd,
- (c8 *)fw->path,
- LINUX_INOTIFY_MASK);
- file_changed = 1;
- }
- if (file_changed)
- fw->fn(fw->path, fw->user_ctx);
- }
- }
- }
- }
-}
-
-static void
update_input(PlatformCtx *ctx)
{
TerminalInput *input = &ctx->input;
@@ -330,10 +267,10 @@ update_input(PlatformCtx *ctx)
FD_ZERO(&rfd);
FD_SET(ctx->child.handle, &rfd);
FD_SET(ctx->inotify_fd, &rfd);
- FD_SET(ctx->x_fd, &rfd);
+ FD_SET(ctx->win_fd, &rfd);
i32 max_fd = MAX(ctx->inotify_fd, ctx->child.handle);
- max_fd = MAX(max_fd, ctx->x_fd);
+ max_fd = MAX(max_fd, ctx->win_fd);
pselect(max_fd + 1, &rfd, NULL, NULL, &timeout, NULL);
input->data_available = FD_ISSET(ctx->child.handle, &rfd) != 0;
@@ -395,22 +332,6 @@ static PLATFORM_WINDOW_TITLE_FN(x11_set_window_title)
glfwSetWindowTitle(linux_ctx.window, (c8 *)buffer->buf);
}
-static PLATFORM_ADD_FILE_WATCH_FN(linux_add_file_watch)
-{
- struct stat sb;
- stat((c8 *)path, &sb);
-
- i32 wd = inotify_add_watch(linux_ctx.inotify_fd, (c8 *)path, LINUX_INOTIFY_MASK);
- i32 idx = linux_ctx.file_watch_count++;
- ASSERT(idx < ARRAY_COUNT(linux_ctx.file_watches));
-
- linux_ctx.file_watches[idx].fn = fn;
- linux_ctx.file_watches[idx].path = path;
- linux_ctx.file_watches[idx].handle = wd;
- linux_ctx.file_watches[idx].inode = sb.st_ino;
- linux_ctx.file_watches[idx].user_ctx = user_ctx;
-}
-
static void
linux_render_thread_entry(struct stack_base *stack)
{
@@ -508,7 +429,6 @@ main(i32 argc, char *argv[], char *envp[])
linux_ctx.memory.platform_api.allocate_ring_buffer = posix_allocate_ring_buffer;
linux_ctx.memory.platform_api.get_clipboard = x11_get_clipboard;
linux_ctx.memory.platform_api.set_clipboard = x11_set_clipboard;
- linux_ctx.memory.platform_api.get_file_stats = posix_get_file_stats;
linux_ctx.memory.platform_api.read_file = posix_read_file;
linux_ctx.memory.platform_api.read = posix_read;
linux_ctx.memory.platform_api.set_terminal_size = posix_set_terminal_size;
diff --git a/util.h b/util.h
@@ -212,9 +212,6 @@ typedef struct {
struct { GL_POST_UNIFORMS } post;
#undef X
- /* TODO: os file watcher */
- FileStats fs_stats[SHADER_COUNT], vs_stats[SHADER_COUNT];
-
_Alignas(16) ShaderParameters shader_parameters;
u32 render_shader_ubo;
u32 render_shader_ssbo;
diff --git a/vtgl.c b/vtgl.c
@@ -117,14 +117,9 @@ static PLATFORM_FILE_WATCH_CALLBACK_FN(reload_shader)
Arena a = t->arena_for_frame;
Stream *err = &t->error_stream;
- b32 success = 1;
-
- FileStats fs_stats = platform->get_file_stats(path);
- Stream fs_text = stream_alloc(&a, fs_stats.size);
- success &= platform->read_file(path, &fs_text, fs_stats.size);
-
- if (success) {
- u32 program = program_from_shader_text(s8(VERTEX_SHADER_TEXT), stream_to_s8(&fs_text), a);
+ s8 fs_text = platform->read_file(path, &a);
+ if (fs_text.len) {
+ u32 program = program_from_shader_text(s8(VERTEX_SHADER_TEXT), fs_text, a);
if (program) {
glDeleteProgram(t->gl.programs[ctx->stage]);
t->gl.programs[ctx->stage] = program;
diff --git a/vtgl.h b/vtgl.h
@@ -94,11 +94,6 @@ typedef struct {
b32 errors;
} Stream;
-typedef struct {
- size size;
- u64 timestamp;
-} FileStats;
-
/* NOTE: virtual memory ring buffer */
typedef struct {
size cap;
@@ -143,10 +138,7 @@ typedef PLATFORM_ALLOCATE_RING_BUFFER_FN(platform_allocate_ring_buffer_fn);
#define PLATFORM_CLIPBOARD_FN(name) b32 name(Stream *buffer, u32 clipboard)
typedef PLATFORM_CLIPBOARD_FN(platform_clipboard_fn);
-#define PLATFORM_GET_FILESTATS_FN(name) FileStats name(u8 *path)
-typedef PLATFORM_GET_FILESTATS_FN(platform_get_file_stats_fn);
-
-#define PLATFORM_READ_FILE_FN(name) b32 name(u8 *path, Stream *buffer, size file_size)
+#define PLATFORM_READ_FILE_FN(name) s8 name(u8 *path, Arena *a)
typedef PLATFORM_READ_FILE_FN(platform_read_file_fn);
/* TODO: this should possibly just take a stream buffer */
@@ -168,7 +160,6 @@ typedef struct {
platform_allocate_ring_buffer_fn *allocate_ring_buffer;
platform_clipboard_fn *get_clipboard;
platform_clipboard_fn *set_clipboard;
- platform_get_file_stats_fn *get_file_stats;
platform_read_file_fn *read_file;
platform_read_fn *read;
platform_set_terminal_size_fn *set_terminal_size;