aboutsummaryrefslogtreecommitdiff
path: root/lib/std/process.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-03-16 17:33:24 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-03-16 17:33:24 -0700
commit1ed569e0b23c4432cd00604dcae89a17edc852a9 (patch)
tree090e0b3817a0caa4f3e7b99ec1d4d965f2bc7438 /lib/std/process.zig
parent778ca2ae6bf025edb6babeec08c957be1fbb37a5 (diff)
parentb4d58e93ea4d0bbfe674f80d301279d302fe8fc8 (diff)
downloadzig-1ed569e0b23c4432cd00604dcae89a17edc852a9.tar.gz
zig-1ed569e0b23c4432cd00604dcae89a17edc852a9.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'lib/std/process.zig')
-rw-r--r--lib/std/process.zig66
1 files changed, 48 insertions, 18 deletions
diff --git a/lib/std/process.zig b/lib/std/process.zig
index eff29e86fa..d06a012af2 100644
--- a/lib/std/process.zig
+++ b/lib/std/process.zig
@@ -828,24 +828,6 @@ pub fn argsWithAllocator(allocator: Allocator) ArgIterator.InitError!ArgIterator
return ArgIterator.initWithAllocator(allocator);
}
-test "args iterator" {
- var ga = std.testing.allocator;
- var it = try argsWithAllocator(ga);
- defer it.deinit(); // no-op unless WASI or Windows
-
- const prog_name = it.next() orelse unreachable;
- const expected_suffix = switch (builtin.os.tag) {
- .wasi => "test.wasm",
- .windows => "test.exe",
- else => "test",
- };
- const given_suffix = std.fs.path.basename(prog_name);
-
- try testing.expect(mem.eql(u8, expected_suffix, given_suffix));
- try testing.expect(it.next() == null);
- try testing.expect(!it.skip());
-}
-
/// Caller must call argsFree on result.
pub fn argsAlloc(allocator: Allocator) ![][:0]u8 {
// TODO refactor to only make 1 allocation.
@@ -1169,3 +1151,51 @@ pub fn execve(
return os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp);
}
+
+pub const TotalSystemMemoryError = error{
+ UnknownTotalSystemMemory,
+};
+
+/// Returns the total system memory, in bytes.
+pub fn totalSystemMemory() TotalSystemMemoryError!usize {
+ switch (builtin.os.tag) {
+ .linux => {
+ return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
+ },
+ .windows => {
+ var kilobytes: std.os.windows.ULONGLONG = undefined;
+ assert(std.os.windows.kernel32.GetPhysicallyInstalledSystemMemory(&kilobytes) == std.os.windows.TRUE);
+ return kilobytes * 1024;
+ },
+ else => return error.UnknownTotalSystemMemory,
+ }
+}
+
+fn totalSystemMemoryLinux() !usize {
+ var file = try std.fs.openFileAbsoluteZ("/proc/meminfo", .{});
+ defer file.close();
+ var buf: [50]u8 = undefined;
+ const amt = try file.read(&buf);
+ if (amt != 50) return error.Unexpected;
+ var it = std.mem.tokenize(u8, buf[0..amt], " \n");
+ const label = it.next().?;
+ if (!std.mem.eql(u8, label, "MemTotal:")) return error.Unexpected;
+ const int_text = it.next() orelse return error.Unexpected;
+ const units = it.next() orelse return error.Unexpected;
+ if (!std.mem.eql(u8, units, "kB")) return error.Unexpected;
+ const kilobytes = try std.fmt.parseInt(usize, int_text, 10);
+ return kilobytes * 1024;
+}
+
+/// Indicate that we are now terminating with a successful exit code.
+/// In debug builds, this is a no-op, so that the calling code's
+/// cleanup mechanisms are tested and so that external tools that
+/// check for resource leaks can be accurate. In release builds, this
+/// calls exit(0), and does not return.
+pub fn cleanExit() void {
+ if (builtin.mode == .Debug) {
+ return;
+ } else {
+ exit(0);
+ }
+}