Skip to content

Commit 326f254

Browse files
authored
std.posix.getenv: early-return comparison (#23265)
Fixes std.posix.getenv() being slower than musl getenv() even when linking libc
1 parent fa59153 commit 326f254

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

lib/std/posix.zig

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,14 +2007,18 @@ pub fn getenv(key: []const u8) ?[:0]const u8 {
20072007
if (native_os == .windows) {
20082008
@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.");
20092009
}
2010+
if (mem.indexOfScalar(u8, key, '=') != null) {
2011+
return null;
2012+
}
20102013
if (builtin.link_libc) {
20112014
var ptr = std.c.environ;
20122015
while (ptr[0]) |line| : (ptr += 1) {
20132016
var line_i: usize = 0;
2014-
while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
2015-
const this_key = line[0..line_i];
2016-
2017-
if (!mem.eql(u8, this_key, key)) continue;
2017+
while (line[line_i] != 0) : (line_i += 1) {
2018+
if (line_i == key.len) break;
2019+
if (line[line_i] != key[line_i]) break;
2020+
}
2021+
if ((line_i != key.len) or (line[line_i] != '=')) continue;
20182022

20192023
return mem.sliceTo(line + line_i + 1, 0);
20202024
}
@@ -2028,9 +2032,11 @@ pub fn getenv(key: []const u8) ?[:0]const u8 {
20282032
// TODO see https://github.com/ziglang/zig/issues/4524
20292033
for (std.os.environ) |ptr| {
20302034
var line_i: usize = 0;
2031-
while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
2032-
const this_key = ptr[0..line_i];
2033-
if (!mem.eql(u8, key, this_key)) continue;
2035+
while (ptr[line_i] != 0) : (line_i += 1) {
2036+
if (line_i == key.len) break;
2037+
if (ptr[line_i] != key[line_i]) break;
2038+
}
2039+
if ((line_i != key.len) or (ptr[line_i] != '=')) continue;
20342040

20352041
return mem.sliceTo(ptr + line_i + 1, 0);
20362042
}

lib/std/posix/test.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,11 @@ test "getenv" {
733733
if (native_os == .windows) {
734734
try expect(std.process.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null);
735735
} else {
736+
try expect(posix.getenv("") == null);
737+
try expect(posix.getenv("BOGUSDOESNOTEXISTENVVAR") == null);
738+
if (builtin.link_libc) {
739+
try testing.expectEqualStrings(posix.getenv("USER") orelse "", mem.span(std.c.getenv("USER") orelse ""));
740+
}
736741
try expect(posix.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
737742
}
738743
}

0 commit comments

Comments
 (0)