vtgl

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

Commit: 00d37df0f277b6902d05f3a99c8c8a994078fc23
Parent: a5a679470ba738a710e43b04dfc5de04f6361c1d
Author: Randy Palamar
Date:   Thu,  5 Dec 2024 07:04:56 -0700

replace getenv

lookup in the pwd database was also removed because it is
completely unnecessary. Even xterm doesn't go and look all this
stuff up. Most of it is already going to be set by virtue of
logging in and starting X.

Diffstat:
Mos_unix.c | 22+++++-----------------
Mplatform_linux_common.c | 13+++++++++++--
Mplatform_linux_x11.c | 2+-
Mutil.c | 41+++++++++++++++++++++++++++++++++++++++++
4 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/os_unix.c b/os_unix.c @@ -1,30 +1,18 @@ /* See LICENSE for copyright details */ -#include <pwd.h> #include <sys/select.h> #include <unistd.h> __attribute__((noreturn)) static void -execsh(char *defcmd) +execsh(s8 cmd, c8 **envp) { - char *sh; - struct passwd *pw; + ASSERT(cmd.data[cmd.len] == 0); - if ((pw = getpwuid(getuid())) == NULL) - os_fatal(s8("are you real?\n")); - - if ((sh = getenv("SHELL")) == NULL) - sh = pw->pw_shell[0] ? pw->pw_shell : defcmd; - - char *argv[] = {sh, NULL}; - setenv("USER", pw->pw_name, 1); - setenv("LOGNAME", pw->pw_name, 1); - setenv("SHELL", sh, 1); - setenv("HOME", pw->pw_dir, 1); + u8 *argv[] = {cmd.data, 0}; /* TODO: don't pretend to be xterm ? */ - setenv("TERM", "xterm", 1); + setenv("TERM", "xterm", 1); - execvp(sh, argv); + execvp((c8 *)cmd.data, (c8 **)argv); syscall1(SYS_exit_group, 1); __builtin_unreachable(); diff --git a/platform_linux_common.c b/platform_linux_common.c @@ -289,9 +289,9 @@ os_child_exited(iptr pid) return r == pid && W_IF_EXITED(status); } -static void execsh(char *); +static void execsh(s8); static linux_platform_process -os_fork_child(char *cmd) +os_fork_child(s8 cmd) { i32 n = 0; @@ -423,4 +423,13 @@ usage(char *argv0, Stream *err) os_fatal(stream_to_s8(err)); } +static s8 +get_default_cmd(char **envp) +{ + s8 result = envp_lookup(s8("SHELL="), envp); + if (result.len == 0) + result = s8("/bin/sh"); + return result; +} + #include "os_unix.c" diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -457,7 +457,7 @@ 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("/bin/sh"); + 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 @@ -221,6 +221,26 @@ c_str_to_s8(char *s) return result; } +static b32 +s8_equal(s8 a, s8 b) +{ + b32 result = a.len == b.len; + for (size i = 0; result && i < a.len; i++) + result = a.data[i] == b.data[i]; + return result; +} + +static b32 +s8_prefix_of(s8 s, s8 match) +{ + b32 result = 0; + if (s.len <= match.len) { + s8 head = {.data = match.data, .len = s.len}; + result = s8_equal(s, head); + } + return result; +} + static struct conversion_result i32_from_cstr(char *s, char delim) { @@ -425,6 +445,27 @@ selection_next(SelectionIterator *s) return result; } +static s8 +envp_lookup(s8 name, char **e) +{ + ASSERT(name.data[name.len - 1] == '='); + + s8 s, result = {0}; + for (; *e; e++) { + s = c_str_to_s8(*e); + if (s8_prefix_of(name, s)) + break; + } + + if (*e) { + result = s; + result.len -= name.len; + result.data += name.len; + } + + return result; +} + static b32 any_mouse_down(TerminalInput *input) {