Commit: bce2aa1f7965ced85c9c3cc2ce4a4390e14f8b8b
Parent: 00d37df0f277b6902d05f3a99c8c8a994078fc23
Author: Randy Palamar
Date: Thu, 5 Dec 2024 21:58:43 -0700
replace setenv/execvp
Diffstat:
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);