mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
os: rename env to be posix-like, do not allocate on posix
This commit is contained in:
@ -243,9 +243,9 @@ pub const GlobalState = struct {
|
|||||||
// maybe once for logging) so for now this is an easy way to do
|
// maybe once for logging) so for now this is an easy way to do
|
||||||
// this. Env vars are useful for logging too because they are
|
// this. Env vars are useful for logging too because they are
|
||||||
// easy to set.
|
// easy to set.
|
||||||
if ((try internal_os.getEnvVarOwned(self.alloc, "GHOSTTY_LOG"))) |v| {
|
if ((try internal_os.getenv(self.alloc, "GHOSTTY_LOG"))) |v| {
|
||||||
defer self.alloc.free(v);
|
defer v.deinit(self.alloc);
|
||||||
if (v.len > 0) {
|
if (v.value.len > 0) {
|
||||||
self.logging = .{ .stderr = {} };
|
self.logging = .{ .stderr = {} };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,61 @@ pub fn appendEnv(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The result of getenv, with a shared deinit to properly handle allocation
|
||||||
|
/// on Windows.
|
||||||
|
pub const GetEnvResult = struct {
|
||||||
|
value: []const u8,
|
||||||
|
|
||||||
|
pub fn deinit(self: GetEnvResult, alloc: Allocator) void {
|
||||||
|
switch (builtin.os.tag) {
|
||||||
|
.windows => alloc.free(self.value),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Gets the value of an environment variable, or null if not found.
|
||||||
|
/// This will allocate on Windows but not on other platforms. The returned
|
||||||
|
/// value should have deinit called to do the proper cleanup no matter what
|
||||||
|
/// platform you are on.
|
||||||
|
pub fn getenv(alloc: Allocator, key: []const u8) !?GetEnvResult {
|
||||||
|
return switch (builtin.os.tag) {
|
||||||
|
// Non-Windows doesn't need to allocate
|
||||||
|
else => if (std.os.getenv(key)) |v| .{ .value = v } else null,
|
||||||
|
|
||||||
|
// Windows needs to allocate
|
||||||
|
.windows => if (std.process.getEnvVarOwned(alloc, key)) |v| .{
|
||||||
|
.value = v,
|
||||||
|
} else |err| switch (err) {
|
||||||
|
error.EnvironmentVariableNotFound => null,
|
||||||
|
else => err,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setenv(key: [:0]const u8, value: [:0]const u8) c_int {
|
||||||
|
return switch (builtin.os.tag) {
|
||||||
|
.windows => c._putenv_s(key.ptr, value.ptr),
|
||||||
|
else => c.setenv(key.ptr, value.ptr, 1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unsetenv(key: [:0]const u8) c_int {
|
||||||
|
return switch (builtin.os.tag) {
|
||||||
|
.windows => c._putenv_s(key.ptr, ""),
|
||||||
|
else => c.unsetenv(key.ptr),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const c = struct {
|
||||||
|
// POSIX
|
||||||
|
extern "c" fn setenv(name: ?[*]const u8, value: ?[*]const u8, overwrite: c_int) c_int;
|
||||||
|
extern "c" fn unsetenv(name: ?[*]const u8) c_int;
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
extern "c" fn _putenv_s(varname: ?[*]const u8, value_string: ?[*]const u8) c_int;
|
||||||
|
};
|
||||||
|
|
||||||
test "appendEnv empty" {
|
test "appendEnv empty" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
@ -46,36 +101,3 @@ test "appendEnv existing" {
|
|||||||
try testing.expectEqualStrings(result, "a:b:foo");
|
try testing.expectEqualStrings(result, "a:b:foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "c" fn setenv(name: ?[*]const u8, value: ?[*]const u8, overwrite: c_int) c_int;
|
|
||||||
extern "c" fn unsetenv(name: ?[*]const u8) c_int;
|
|
||||||
extern "c" fn _putenv_s(varname: ?[*]const u8, value_string: ?[*]const u8) c_int;
|
|
||||||
|
|
||||||
pub fn setEnv(key: [:0]const u8, value: [:0]const u8) c_int {
|
|
||||||
if (builtin.os.tag == .windows) {
|
|
||||||
return _putenv_s(key.ptr, value.ptr);
|
|
||||||
} else {
|
|
||||||
return setenv(key.ptr, value.ptr, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unsetEnv(key: [:0]const u8) c_int {
|
|
||||||
if (builtin.os.tag == .windows) {
|
|
||||||
return _putenv_s(key.ptr, "");
|
|
||||||
} else {
|
|
||||||
return unsetenv(key.ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the value of an environment variable, or null if not found.
|
|
||||||
/// The returned value is always allocated so it must be freed.
|
|
||||||
pub fn getEnvVarOwned(alloc: std.mem.Allocator, key: []const u8) !?[]u8 {
|
|
||||||
if (std.process.getEnvVarOwned(alloc, key)) |v| {
|
|
||||||
return v;
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.EnvironmentVariableNotFound => {},
|
|
||||||
else => return err,
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
@ -12,8 +12,8 @@ pub fn ensureLocale(alloc: std.mem.Allocator) !void {
|
|||||||
|
|
||||||
// Get our LANG env var. We use this many times but we also need
|
// Get our LANG env var. We use this many times but we also need
|
||||||
// the original value later.
|
// the original value later.
|
||||||
const lang = try internal_os.getEnvVarOwned(alloc, "LANG");
|
const lang = try internal_os.getenv(alloc, "LANG");
|
||||||
defer if (lang) |v| alloc.free(v);
|
defer if (lang) |v| v.deinit(alloc);
|
||||||
|
|
||||||
// On macOS, pre-populate the LANG env var with system preferences.
|
// On macOS, pre-populate the LANG env var with system preferences.
|
||||||
// When launching the .app, LANG is not set so we must query it from the
|
// When launching the .app, LANG is not set so we must query it from the
|
||||||
@ -22,7 +22,7 @@ pub fn ensureLocale(alloc: std.mem.Allocator) !void {
|
|||||||
if (comptime builtin.target.isDarwin()) {
|
if (comptime builtin.target.isDarwin()) {
|
||||||
// Set the lang if it is not set or if its empty.
|
// Set the lang if it is not set or if its empty.
|
||||||
if (lang) |l| {
|
if (lang) |l| {
|
||||||
if (l.len == 0) {
|
if (l.value.len == 0) {
|
||||||
setLangFromCocoa();
|
setLangFromCocoa();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,13 +37,13 @@ pub fn ensureLocale(alloc: std.mem.Allocator) !void {
|
|||||||
// setlocale failed. This is probably because the LANG env var is
|
// setlocale failed. This is probably because the LANG env var is
|
||||||
// invalid. Try to set it without the LANG var set to use the system
|
// invalid. Try to set it without the LANG var set to use the system
|
||||||
// default.
|
// default.
|
||||||
if ((try internal_os.getEnvVarOwned(alloc, "LANG"))) |old_lang| {
|
if ((try internal_os.getenv(alloc, "LANG"))) |old_lang| {
|
||||||
defer alloc.free(old_lang);
|
defer old_lang.deinit(alloc);
|
||||||
if (old_lang.len > 0) {
|
if (old_lang.value.len > 0) {
|
||||||
// We don't need to do both of these things but we do them
|
// We don't need to do both of these things but we do them
|
||||||
// both to be sure that lang is either empty or unset completely.
|
// both to be sure that lang is either empty or unset completely.
|
||||||
_ = internal_os.setEnv("LANG", "");
|
_ = internal_os.setenv("LANG", "");
|
||||||
_ = internal_os.unsetEnv("LANG");
|
_ = internal_os.unsetenv("LANG");
|
||||||
|
|
||||||
if (setlocale(LC_ALL, "")) |v| {
|
if (setlocale(LC_ALL, "")) |v| {
|
||||||
log.info("setlocale after unset lang result={s}", .{v});
|
log.info("setlocale after unset lang result={s}", .{v});
|
||||||
@ -59,7 +59,7 @@ pub fn ensureLocale(alloc: std.mem.Allocator) !void {
|
|||||||
// Failure again... fallback to en_US.UTF-8
|
// Failure again... fallback to en_US.UTF-8
|
||||||
log.warn("setlocale failed with LANG and system default. Falling back to en_US.UTF-8", .{});
|
log.warn("setlocale failed with LANG and system default. Falling back to en_US.UTF-8", .{});
|
||||||
if (setlocale(LC_ALL, "en_US.UTF-8")) |v| {
|
if (setlocale(LC_ALL, "en_US.UTF-8")) |v| {
|
||||||
_ = internal_os.setEnv("LANG", "en_US.UTF-8");
|
_ = internal_os.setenv("LANG", "en_US.UTF-8");
|
||||||
log.info("setlocale default result={s}", .{v});
|
log.info("setlocale default result={s}", .{v});
|
||||||
return;
|
return;
|
||||||
} else log.err("setlocale failed even with the fallback, uncertain results", .{});
|
} else log.err("setlocale failed even with the fallback, uncertain results", .{});
|
||||||
@ -100,7 +100,7 @@ fn setLangFromCocoa() void {
|
|||||||
log.info("detected system locale={s}", .{env_value});
|
log.info("detected system locale={s}", .{env_value});
|
||||||
|
|
||||||
// Set it onto our environment
|
// Set it onto our environment
|
||||||
if (internal_os.setEnv("LANG", env_value) < 0) {
|
if (internal_os.setenv("LANG", env_value) < 0) {
|
||||||
log.err("error setting locale env var", .{});
|
log.err("error setting locale env var", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user