From 5e512051190602bbff0f9b06fbb4a9a9bf5a5fff Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 14 Feb 2025 13:26:04 -0800 Subject: [PATCH] thinking of chickening out --- lib/std/os/windows.zig | 40 +++ lib/std/posix.zig | 50 +--- lib/std/process.zig | 565 +++++++++++++++++++---------------------- lib/std/start.zig | 3 - 4 files changed, 303 insertions(+), 355 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 563b24cf83..ef7bd57335 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -5650,3 +5650,43 @@ pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE { const ppeb: *const PEB = @ptrCast(@alignCast(peb_out.ptr)); return ppeb.ImageBaseAddress; } + +/// Get an environment variable with a null-terminated, WTF-16 encoded name. +/// +/// This function performs a Unicode-aware case-insensitive lookup using RtlEqualUnicodeString. +/// +/// See also: +/// * `std.process.Init.Env.map` +/// * `std.process.Init.Env.getOwned` +/// * `std.process.Init.Env.hasConstant` +/// * `std.process.Init.Env.has` +pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { + const key_slice = mem.sliceTo(key, 0); + const ptr = peb().ProcessParameters.Environment; + var i: usize = 0; + while (ptr[i] != 0) { + const key_start = i; + + // There are some special environment variables that start with =, + // so we need a special case to not treat = as a key/value separator + // if it's the first character. + // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 + if (ptr[key_start] == '=') i += 1; + + while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {} + const this_key = ptr[key_start..i]; + + if (ptr[i] == '=') i += 1; + + const value_start = i; + while (ptr[i] != 0) : (i += 1) {} + const this_value = ptr[value_start..i :0]; + + if (eqlIgnoreCaseWTF16(key_slice, this_key)) { + return this_value; + } + + i += 1; // skip over null byte + } + return null; +} diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 011a6723d1..c17874fe8c 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -1985,54 +1985,8 @@ pub fn execvpeZ( return execvpeZ_expandArg0(.no_expand, file, argv_ptr, envp); } -/// Get an environment variable. -/// See also `getenvZ`. -pub fn getenv(key: []const u8) ?[:0]const u8 { - if (native_os == .windows) { - @compileError("std.posix.getenv is unavailable for Windows because environment strings are in WTF-16 format. See std.process.getEnvVarOwned for a cross-platform API or std.process.getenvW for a Windows-specific API."); - } - if (builtin.link_libc) { - var ptr = std.c.environ; - while (ptr[0]) |line| : (ptr += 1) { - var line_i: usize = 0; - while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} - const this_key = line[0..line_i]; - - if (!mem.eql(u8, this_key, key)) continue; - - return mem.sliceTo(line + line_i + 1, 0); - } - return null; - } - if (native_os == .wasi) { - @compileError("std.posix.getenv is unavailable for WASI. See std.process.getEnvMap or std.process.getEnvVarOwned for a cross-platform API."); - } - // The simplified start logic doesn't populate environ. - if (std.start.simplified_logic) return null; - // TODO see https://github.com/ziglang/zig/issues/4524 - for (std.os.environ) |ptr| { - var line_i: usize = 0; - while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {} - const this_key = ptr[0..line_i]; - if (!mem.eql(u8, key, this_key)) continue; - - return mem.sliceTo(ptr + line_i + 1, 0); - } - return null; -} - -/// Get an environment variable with a null-terminated name. -/// See also `getenv`. -pub fn getenvZ(key: [*:0]const u8) ?[:0]const u8 { - if (builtin.link_libc) { - const value = system.getenv(key) orelse return null; - return mem.sliceTo(value, 0); - } - if (native_os == .windows) { - @compileError("std.posix.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.process.getenvW for Windows-specific API."); - } - return getenv(mem.sliceTo(key, 0)); -} +pub const getenv = @compileError("environment variables are passed as an argument to the main function"); +pub const getenvZ = getenv; pub const GetCwdError = error{ NameTooLong, diff --git a/lib/std/process.zig b/lib/std/process.zig index 1bd41a638c..ee3ab98126 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -568,6 +568,267 @@ pub const Init = struct { .freestanding, .other, .windows, .wasi => void, else => [][*:0]u8, }; + + /// On Windows, `key` must be valid UTF-8. + pub fn hasConstant(comptime key: []const u8) bool { + if (native_os == .windows) { + const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key); + return windows.getenvW(key_w) != null; + } else if (native_os == .wasi and !builtin.link_libc) { + @compileError("hasConstant is not supported for WASI without libc"); + } else { + return posix.getenv(key) != null; + } + } + + /// On Windows, `key` must be valid UTF-8. + pub fn hasNonEmptyConstant(comptime key: []const u8) bool { + if (native_os == .windows) { + const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key); + const value = windows.getenvW(key_w) orelse return false; + return value.len != 0; + } else if (native_os == .wasi and !builtin.link_libc) { + @compileError("hasNonEmptyEnvVarConstant is not supported for WASI without libc"); + } else { + const value = posix.getenv(key) orelse return false; + return value.len != 0; + } + } + + pub const ParseIntError = std.fmt.ParseIntError || error{EnvironmentVariableNotFound}; + + /// Parses an environment variable as an integer. + /// + /// Since the key is comptime-known, no allocation is needed. + /// + /// On Windows, `key` must be valid UTF-8. + pub fn parseInt(comptime key: []const u8, comptime I: type, base: u8) ParseIntError!I { + if (native_os == .windows) { + const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key); + const text = windows.getenvW(key_w) orelse return error.EnvironmentVariableNotFound; + return std.fmt.parseIntWithGenericCharacter(I, u16, text, base); + } else if (native_os == .wasi and !builtin.link_libc) { + @compileError("not supported for WASI without libc"); + } else { + const text = posix.getenv(key) orelse return error.EnvironmentVariableNotFound; + return std.fmt.parseInt(I, text, base); + } + } + + pub const HasError = error{ + OutOfMemory, + + /// On Windows, environment variable keys provided by the user must be valid WTF-8. + /// https://simonsapin.github.io/wtf-8/ + InvalidWtf8, + }; + + /// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), + /// then `error.InvalidWtf8` is returned. + pub fn has(allocator: Allocator, key: []const u8) HasError!bool { + if (native_os == .windows) { + var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); + const stack_allocator = stack_alloc.get(); + const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); + defer stack_allocator.free(key_w); + return windows.getenvW(key_w) != null; + } else if (native_os == .wasi and !builtin.link_libc) { + var m = map(allocator) catch return error.OutOfMemory; + defer m.deinit(); + return m.getPtr(key) != null; + } else { + return posix.getenv(key) != null; + } + } + + /// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), + /// then `error.InvalidWtf8` is returned. + pub fn hasNonEmpty(allocator: Allocator, key: []const u8) HasError!bool { + if (native_os == .windows) { + var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); + const stack_allocator = stack_alloc.get(); + const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); + defer stack_allocator.free(key_w); + const value = windows.getenvW(key_w) orelse return false; + return value.len != 0; + } else if (native_os == .wasi and !builtin.link_libc) { + var m = map(allocator) catch return error.OutOfMemory; + defer m.deinit(); + const value = m.getPtr(key) orelse return false; + return value.len != 0; + } else { + const value = posix.getenv(key) orelse return false; + return value.len != 0; + } + } + + pub const MapError = error{ + OutOfMemory, + /// WASI-only. `environ_sizes_get` or `environ_get` + /// failed for an unexpected reason. + Unexpected, + }; + + /// Returns a snapshot of the environment variables of the current process. + /// Any modifications to the resulting `EnvMap` will not be reflected + /// in the environment, and likewise, any future modifications to the + /// environment will not be reflected in the `EnvMap`. + /// Caller owns resulting `EnvMap` and should call its `deinit` fn when done. + pub fn map(allocator: Allocator) MapError!EnvMap { + var result = EnvMap.init(allocator); + errdefer result.deinit(); + + if (native_os == .windows) { + const ptr = windows.peb().ProcessParameters.Environment; + + var i: usize = 0; + while (ptr[i] != 0) { + const key_start = i; + + // There are some special environment variables that start with =, + // so we need a special case to not treat = as a key/value separator + // if it's the first character. + // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 + if (ptr[key_start] == '=') i += 1; + + while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {} + const key_w = ptr[key_start..i]; + const key = try unicode.wtf16LeToWtf8Alloc(allocator, key_w); + errdefer allocator.free(key); + + if (ptr[i] == '=') i += 1; + + const value_start = i; + while (ptr[i] != 0) : (i += 1) {} + const value_w = ptr[value_start..i]; + const value = try unicode.wtf16LeToWtf8Alloc(allocator, value_w); + errdefer allocator.free(value); + + i += 1; // skip over null byte + + try result.putMove(key, value); + } + return result; + } else if (native_os == .wasi and !builtin.link_libc) { + var environ_count: usize = undefined; + var environ_buf_size: usize = undefined; + + const environ_sizes_get_ret = std.os.wasi.environ_sizes_get(&environ_count, &environ_buf_size); + if (environ_sizes_get_ret != .SUCCESS) { + return posix.unexpectedErrno(environ_sizes_get_ret); + } + + if (environ_count == 0) { + return result; + } + + const environ = try allocator.alloc([*:0]u8, environ_count); + defer allocator.free(environ); + const environ_buf = try allocator.alloc(u8, environ_buf_size); + defer allocator.free(environ_buf); + + const environ_get_ret = std.os.wasi.environ_get(environ.ptr, environ_buf.ptr); + if (environ_get_ret != .SUCCESS) { + return posix.unexpectedErrno(environ_get_ret); + } + + for (environ) |env| { + const pair = mem.sliceTo(env, 0); + var parts = mem.splitScalar(u8, pair, '='); + const key = parts.first(); + const value = parts.rest(); + try result.put(key, value); + } + return result; + } else if (builtin.link_libc) { + var ptr = std.c.environ; + while (ptr[0]) |line| : (ptr += 1) { + var line_i: usize = 0; + while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} + const key = line[0..line_i]; + + var end_i: usize = line_i; + while (line[end_i] != 0) : (end_i += 1) {} + const value = line[line_i + 1 .. end_i]; + + try result.put(key, value); + } + return result; + } else { + for (std.os.environ) |line| { + var line_i: usize = 0; + while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} + const key = line[0..line_i]; + + var end_i: usize = line_i; + while (line[end_i] != 0) : (end_i += 1) {} + const value = line[line_i + 1 .. end_i]; + + try result.put(key, value); + } + return result; + } + } + + test map { + var env = try map(testing.allocator); + defer env.deinit(); + } + + pub const GetOwnedError = error{ + OutOfMemory, + EnvironmentVariableNotFound, + + /// On Windows, environment variable keys provided by the user must be valid WTF-8. + /// https://simonsapin.github.io/wtf-8/ + InvalidWtf8, + }; + + /// Caller must free returned memory. + /// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), + /// then `error.InvalidWtf8` is returned. + /// On Windows, the value is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). + /// On other platforms, the value is an opaque sequence of bytes with no particular encoding. + pub fn getOwned(allocator: Allocator, key: []const u8) GetOwnedError![]u8 { + if (native_os == .windows) { + const result_w = blk: { + var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); + const stack_allocator = stack_alloc.get(); + const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); + defer stack_allocator.free(key_w); + + break :blk windows.getenvW(key_w) orelse return error.EnvironmentVariableNotFound; + }; + // wtf16LeToWtf8Alloc can only fail with OutOfMemory + return unicode.wtf16LeToWtf8Alloc(allocator, result_w); + } else if (native_os == .wasi and !builtin.link_libc) { + var m = map(allocator) catch return error.OutOfMemory; + defer m.deinit(); + const val = m.get(key) orelse return error.EnvironmentVariableNotFound; + return allocator.dupe(u8, val); + } else { + const result = posix.getenv(key) orelse return error.EnvironmentVariableNotFound; + return allocator.dupe(u8, result); + } + } + + test getOwned { + try testing.expectError( + error.EnvironmentVariableNotFound, + getOwned(std.testing.allocator, "BADENV"), + ); + } + + test hasConstant { + if (native_os == .wasi and !builtin.link_libc) return error.SkipZigTest; + + try testing.expect(!hasConstant("BADENV")); + } + + test has { + const has_env = try has(std.testing.allocator, "BADENV"); + try testing.expect(!has_env); + } }; pub const Aux = struct { @@ -833,310 +1094,6 @@ test EnvMap { } } -pub const GetEnvMapError = error{ - OutOfMemory, - /// WASI-only. `environ_sizes_get` or `environ_get` - /// failed for an unexpected reason. - Unexpected, -}; - -/// Returns a snapshot of the environment variables of the current process. -/// Any modifications to the resulting EnvMap will not be reflected in the environment, and -/// likewise, any future modifications to the environment will not be reflected in the EnvMap. -/// Caller owns resulting `EnvMap` and should call its `deinit` fn when done. -pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap { - var result = EnvMap.init(allocator); - errdefer result.deinit(); - - if (native_os == .windows) { - const ptr = windows.peb().ProcessParameters.Environment; - - var i: usize = 0; - while (ptr[i] != 0) { - const key_start = i; - - // There are some special environment variables that start with =, - // so we need a special case to not treat = as a key/value separator - // if it's the first character. - // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 - if (ptr[key_start] == '=') i += 1; - - while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {} - const key_w = ptr[key_start..i]; - const key = try unicode.wtf16LeToWtf8Alloc(allocator, key_w); - errdefer allocator.free(key); - - if (ptr[i] == '=') i += 1; - - const value_start = i; - while (ptr[i] != 0) : (i += 1) {} - const value_w = ptr[value_start..i]; - const value = try unicode.wtf16LeToWtf8Alloc(allocator, value_w); - errdefer allocator.free(value); - - i += 1; // skip over null byte - - try result.putMove(key, value); - } - return result; - } else if (native_os == .wasi and !builtin.link_libc) { - var environ_count: usize = undefined; - var environ_buf_size: usize = undefined; - - const environ_sizes_get_ret = std.os.wasi.environ_sizes_get(&environ_count, &environ_buf_size); - if (environ_sizes_get_ret != .SUCCESS) { - return posix.unexpectedErrno(environ_sizes_get_ret); - } - - if (environ_count == 0) { - return result; - } - - const environ = try allocator.alloc([*:0]u8, environ_count); - defer allocator.free(environ); - const environ_buf = try allocator.alloc(u8, environ_buf_size); - defer allocator.free(environ_buf); - - const environ_get_ret = std.os.wasi.environ_get(environ.ptr, environ_buf.ptr); - if (environ_get_ret != .SUCCESS) { - return posix.unexpectedErrno(environ_get_ret); - } - - for (environ) |env| { - const pair = mem.sliceTo(env, 0); - var parts = mem.splitScalar(u8, pair, '='); - const key = parts.first(); - const value = parts.rest(); - try result.put(key, value); - } - return result; - } else if (builtin.link_libc) { - var ptr = std.c.environ; - while (ptr[0]) |line| : (ptr += 1) { - var line_i: usize = 0; - while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} - const key = line[0..line_i]; - - var end_i: usize = line_i; - while (line[end_i] != 0) : (end_i += 1) {} - const value = line[line_i + 1 .. end_i]; - - try result.put(key, value); - } - return result; - } else { - for (std.os.environ) |line| { - var line_i: usize = 0; - while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} - const key = line[0..line_i]; - - var end_i: usize = line_i; - while (line[end_i] != 0) : (end_i += 1) {} - const value = line[line_i + 1 .. end_i]; - - try result.put(key, value); - } - return result; - } -} - -test getEnvMap { - var env = try getEnvMap(testing.allocator); - defer env.deinit(); -} - -pub const GetEnvVarOwnedError = error{ - OutOfMemory, - EnvironmentVariableNotFound, - - /// On Windows, environment variable keys provided by the user must be valid WTF-8. - /// https://simonsapin.github.io/wtf-8/ - InvalidWtf8, -}; - -/// Caller must free returned memory. -/// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), -/// then `error.InvalidWtf8` is returned. -/// On Windows, the value is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). -/// On other platforms, the value is an opaque sequence of bytes with no particular encoding. -pub fn getEnvVarOwned(allocator: Allocator, key: []const u8) GetEnvVarOwnedError![]u8 { - if (native_os == .windows) { - const result_w = blk: { - var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); - const stack_allocator = stack_alloc.get(); - const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); - defer stack_allocator.free(key_w); - - break :blk getenvW(key_w) orelse return error.EnvironmentVariableNotFound; - }; - // wtf16LeToWtf8Alloc can only fail with OutOfMemory - return unicode.wtf16LeToWtf8Alloc(allocator, result_w); - } else if (native_os == .wasi and !builtin.link_libc) { - var envmap = getEnvMap(allocator) catch return error.OutOfMemory; - defer envmap.deinit(); - const val = envmap.get(key) orelse return error.EnvironmentVariableNotFound; - return allocator.dupe(u8, val); - } else { - const result = posix.getenv(key) orelse return error.EnvironmentVariableNotFound; - return allocator.dupe(u8, result); - } -} - -/// On Windows, `key` must be valid UTF-8. -pub fn hasEnvVarConstant(comptime key: []const u8) bool { - if (native_os == .windows) { - const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key); - return getenvW(key_w) != null; - } else if (native_os == .wasi and !builtin.link_libc) { - @compileError("hasEnvVarConstant is not supported for WASI without libc"); - } else { - return posix.getenv(key) != null; - } -} - -/// On Windows, `key` must be valid UTF-8. -pub fn hasNonEmptyEnvVarConstant(comptime key: []const u8) bool { - if (native_os == .windows) { - const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key); - const value = getenvW(key_w) orelse return false; - return value.len != 0; - } else if (native_os == .wasi and !builtin.link_libc) { - @compileError("hasNonEmptyEnvVarConstant is not supported for WASI without libc"); - } else { - const value = posix.getenv(key) orelse return false; - return value.len != 0; - } -} - -pub const ParseEnvVarIntError = std.fmt.ParseIntError || error{EnvironmentVariableNotFound}; - -/// Parses an environment variable as an integer. -/// -/// Since the key is comptime-known, no allocation is needed. -/// -/// On Windows, `key` must be valid UTF-8. -pub fn parseEnvVarInt(comptime key: []const u8, comptime I: type, base: u8) ParseEnvVarIntError!I { - if (native_os == .windows) { - const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key); - const text = getenvW(key_w) orelse return error.EnvironmentVariableNotFound; - return std.fmt.parseIntWithGenericCharacter(I, u16, text, base); - } else if (native_os == .wasi and !builtin.link_libc) { - @compileError("parseEnvVarInt is not supported for WASI without libc"); - } else { - const text = posix.getenv(key) orelse return error.EnvironmentVariableNotFound; - return std.fmt.parseInt(I, text, base); - } -} - -pub const HasEnvVarError = error{ - OutOfMemory, - - /// On Windows, environment variable keys provided by the user must be valid WTF-8. - /// https://simonsapin.github.io/wtf-8/ - InvalidWtf8, -}; - -/// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), -/// then `error.InvalidWtf8` is returned. -pub fn hasEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool { - if (native_os == .windows) { - var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); - const stack_allocator = stack_alloc.get(); - const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); - defer stack_allocator.free(key_w); - return getenvW(key_w) != null; - } else if (native_os == .wasi and !builtin.link_libc) { - var envmap = getEnvMap(allocator) catch return error.OutOfMemory; - defer envmap.deinit(); - return envmap.getPtr(key) != null; - } else { - return posix.getenv(key) != null; - } -} - -/// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/), -/// then `error.InvalidWtf8` is returned. -pub fn hasNonEmptyEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool { - if (native_os == .windows) { - var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator); - const stack_allocator = stack_alloc.get(); - const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key); - defer stack_allocator.free(key_w); - const value = getenvW(key_w) orelse return false; - return value.len != 0; - } else if (native_os == .wasi and !builtin.link_libc) { - var envmap = getEnvMap(allocator) catch return error.OutOfMemory; - defer envmap.deinit(); - const value = envmap.getPtr(key) orelse return false; - return value.len != 0; - } else { - const value = posix.getenv(key) orelse return false; - return value.len != 0; - } -} - -/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name. -/// -/// This function performs a Unicode-aware case-insensitive lookup using RtlEqualUnicodeString. -/// -/// See also: -/// * `std.posix.getenv` -/// * `getEnvMap` -/// * `getEnvVarOwned` -/// * `hasEnvVarConstant` -/// * `hasEnvVar` -pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { - if (native_os != .windows) { - @compileError("Windows-only"); - } - const key_slice = mem.sliceTo(key, 0); - const ptr = windows.peb().ProcessParameters.Environment; - var i: usize = 0; - while (ptr[i] != 0) { - const key_start = i; - - // There are some special environment variables that start with =, - // so we need a special case to not treat = as a key/value separator - // if it's the first character. - // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 - if (ptr[key_start] == '=') i += 1; - - while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {} - const this_key = ptr[key_start..i]; - - if (ptr[i] == '=') i += 1; - - const value_start = i; - while (ptr[i] != 0) : (i += 1) {} - const this_value = ptr[value_start..i :0]; - - if (windows.eqlIgnoreCaseWTF16(key_slice, this_key)) { - return this_value; - } - - i += 1; // skip over null byte - } - return null; -} - -test getEnvVarOwned { - try testing.expectError( - error.EnvironmentVariableNotFound, - getEnvVarOwned(std.testing.allocator, "BADENV"), - ); -} - -test hasEnvVarConstant { - if (native_os == .wasi and !builtin.link_libc) return error.SkipZigTest; - - try testing.expect(!hasEnvVarConstant("BADENV")); -} - -test hasEnvVar { - const has_env = try hasEnvVar(std.testing.allocator, "BADENV"); - try testing.expect(!has_env); -} - pub const UserInfo = struct { uid: posix.uid_t, gid: posix.gid_t, diff --git a/lib/std/start.zig b/lib/std/start.zig index 0712dab40d..fde42641e0 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -605,9 +605,6 @@ fn expandStackSize(phdrs: []elf.Phdr) void { } inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8, aux: std.process.Init.Aux) u8 { - std.os.argv = argv[0..argc]; // To be removed after 0.15.0 is tagged. - std.os.environ = envp; // To be removed after 0.15.0 is tagged. - std.debug.maybeEnableSegfaultHandler(); maybeIgnoreSigpipe();