vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: bce2aa1f7965ced85c9c3cc2ce4a4390e14f8b8b
Parent: 00d37df0f277b6902d05f3a99c8c8a994078fc23
Author: Randy Palamar
Date:   Thu,  5 Dec 2024 21:58:43 -0700

replace setenv/execvp

Diffstat:
Dos_unix.c | 19-------------------
Mplatform_linux_amd64.c | 1+
Mplatform_linux_common.c | 32++++++++++++++++++++++++++++----
Mplatform_linux_x11.c | 13++++++++++++-
Mutil.c | 16++++++++++++++++
Mutil.h | 37+++++++++++++++++++++++++++++++++++--
Mvtgl.c | 7+++----
7 files changed, 95 insertions(+), 30 deletions(-)

diff --git a/os_unix.c b/os_unix.c @@ -1,19 +0,0 @@ -/* See LICENSE for copyright details */ -#include <sys/select.h> -#include <unistd.h> - -__attribute__((noreturn)) -static void -execsh(s8 cmd, c8 **envp) -{ - ASSERT(cmd.data[cmd.len] == 0); - - u8 *argv[] = {cmd.data, 0}; - /* TODO: don't pretend to be xterm ? */ - setenv("TERM", "xterm", 1); - - execvp((c8 *)cmd.data, (c8 **)argv); - - syscall1(SYS_exit_group, 1); - __builtin_unreachable(); -} diff --git a/platform_linux_amd64.c b/platform_linux_amd64.c @@ -22,6 +22,7 @@ #define SYS_dup2 33 #define SYS_clone 56 #define SYS_fork 57 +#define SYS_execve 59 #define SYS_wait4 61 #define SYS_ftruncate 77 #define SYS_setsid 112 diff --git a/platform_linux_common.c b/platform_linux_common.c @@ -289,9 +289,8 @@ os_child_exited(iptr pid) return r == pid && W_IF_EXITED(status); } -static void execsh(s8); static linux_platform_process -os_fork_child(s8 cmd) +os_fork_child(s8 cmd, c8 **envp) { i32 n = 0; @@ -321,7 +320,11 @@ os_fork_child(s8 cmd) syscall2(SYS_dup2, s, 2); syscall3(SYS_ioctl, s, TIOCSCTTY, 0); if (s > 2) syscall1(SYS_close, s); - execsh(cmd); + ASSERT(cmd.data[cmd.len] == 0); + u8 *argv[] = {cmd.data, 0}; + syscall3(SYS_execve, (iptr)cmd.data, (iptr)argv, (iptr)envp); + __builtin_unreachable(); + os_fatal(s8("failed to exec child\n")); } syscall1(SYS_close, s); @@ -432,4 +435,25 @@ get_default_cmd(char **envp) return result; } -#include "os_unix.c" +static SLLVariableVector +parse_environment(Arena *a, char **envp) +{ + SLLVariableVector env = {0}; + for (; *envp; envp++) { + s8 e = c_str_to_s8(*envp); + if (!s8_prefix_of(s8("TERM="), e)) { + Variable *var = push_struct(a, Variable); + var->type = VT_S8; + var->s8 = e; + SLLVariableVectorPush(a, &env, var); + } + } + + Variable *var = push_struct(a, Variable); + var->type = VT_S8; + /* TODO: don't pretend to be xterm ? */ + var->s8 = s8("TERM=xterm"); + SLLVariableVectorPush(a, &env, var); + + return env; +} diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -240,6 +240,9 @@ init_window(PlatformCtx *ctx, iv2 window_size) return window; } +/* TODO: remove */ +#include <sys/select.h> + static void update_input(PlatformCtx *ctx) { @@ -412,6 +415,15 @@ main(i32 argc, char *argv[], char *envp[]) new_thread(render_stack); { + Arena tmp = linux_ctx.platform_memory; + SLLVariableVector environment_block = parse_environment(&tmp, envp); + + /* TODO: build up argv for the child as well */ + c8 **child_envp = construct_c_str_array(&tmp, environment_block); + linux_ctx.child = os_fork_child(get_default_cmd(envp), child_envp); + } + + { MemoryBlock terminal_memory = linux_block_alloc(MB(32)); linux_ctx.memory.memory = terminal_memory.memory; linux_ctx.memory.memory_size = terminal_memory.size; @@ -457,7 +469,6 @@ main(i32 argc, char *argv[], char *envp[]) iv2 window_size = {.w = 1280, .h = 720}; linux_ctx.window = init_window(&linux_ctx, window_size); - linux_ctx.child = os_fork_child(get_default_cmd(envp)); iv2 requested_size = vtgl_initialize(&linux_ctx.memory, linux_ctx.child.handle, cells, monitor_size); if (requested_size.w > 0 && requested_size.h > 0 && diff --git a/util.c b/util.c @@ -113,6 +113,7 @@ mem_clear(void *p_, u8 c, size len) return p; } +#define push_struct(a, t) alloc(a, t, 1) #define alloc(a, t, n) (t *)alloc_(a, sizeof(t), _Alignof(t), n) static void * alloc_(Arena *a, size len, size align, size count) @@ -466,6 +467,21 @@ envp_lookup(s8 name, char **e) return result; } +static c8 ** +construct_c_str_array(Arena *a, SLLVariableVector vars) +{ + c8 **result = alloc(a, c8 *, vars.count + 1); + + VariableLink *chain = vars.first; + for (u32 i = 0; i < vars.count; i++) { + ASSERT(chain->var->type == VT_S8); + result[i] = (c8 *)chain->var->s8.data; + chain = chain->next; + } + + return result; +} + static b32 any_mouse_down(TerminalInput *input) { diff --git a/util.h b/util.h @@ -32,14 +32,47 @@ enum variable_type { VT_V4, VT_S8, VT_RANGE, - VT_VARIABLE, + VT_SLL_VECTOR, VT_GROUP, }; +struct Variable; + +typedef struct VariableLink { + struct VariableLink *prev; + struct VariableLink *next; + struct Variable *var; +} VariableLink; + typedef struct { + VariableLink *first; + u32 count; +} SLLVariableVector; + +#define SLLVariableVectorPush(a, sll, var) do { \ + VariableLink *vl = push_struct(a, VariableLink); \ + (sll)->count++; \ + vl->next = (sll)->first; \ + vl->var = var; \ + (sll)->first = vl; \ +} while(0) + +typedef struct Variable { enum variable_type type; - void *value; + union { + b32 b32; + u32 u32; + i32 i32; + f32 f32; + s8 s8; + v4 v4; + + Range range; + + VariableLink group; + SLLVariableVector vector; + }; } Variable; enum cell_attribute { diff --git a/vtgl.c b/vtgl.c @@ -976,7 +976,7 @@ should_start_interaction(TerminalInput *input) } static void -begin_interaction(InteractionState *is, TerminalInput *input) +begin_interaction(Term *t, InteractionState *is, TerminalInput *input) { is->click_count++; if (is->multi_click_t < 0) @@ -993,7 +993,7 @@ begin_interaction(InteractionState *is, TerminalInput *input) switch (is->active.type) { case IS_TERM: - begin_terminal_interaction(is->active.var.value, input, is->click_count); + begin_terminal_interaction(t, input, is->click_count); break; default: break; @@ -1024,7 +1024,7 @@ handle_interactions(Term *t, TerminalInput *input, PlatformAPI *platform) if (is->hot.type != IS_NONE) { if (should_start_interaction(input)) { end_interaction(is, input); - begin_interaction(is, input); + begin_interaction(t, is, input); } } @@ -1247,7 +1247,6 @@ DEBUG_EXPORT VTGL_RENDER_FRAME_FN(vtgl_render_frame) /* TODO: if (!t->ui_active) */ { t->interaction.hot.type = IS_TERM; - t->interaction.hot.var = (Variable){.value = t}; } glBindTexture(GL_TEXTURE_2D, t->gl.glyph_bitmap_tex);