authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2020-10-11 13:47:13-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-15 16:54:50-07:00
log1c36680928dec40fd607b43050bdeec53b0b0941
treed4746380eee50e828066b75b95df4ec5839380e0
parente17297102a14620c8d53a3d1f4137314880a28ce

stage2: use execve where available for zig test and zig run

closes #6531

1 files changed, 44 insertions(+), 38 deletions(-)

src/main.zig+44-38
......@@ -2,6 +2,7 @@ const std = @import("std");
22const assert = std.debug.assert;
33const io = std.io;
44const fs = std.fs;
5const os = std.os;
56const mem = std.mem;
67const process = std.process;
78const Allocator = mem.Allocator;
......@@ -1742,47 +1743,52 @@ fn buildOutputType(
17421743 if (runtime_args_start) |i| {
17431744 try argv.appendSlice(all_args[i..]);
17441745 }
1745 // TODO On operating systems that support it, do an execve here rather than child process,
1746 // when watch=false and arg_mode == .run
1747 const child = try std.ChildProcess.init(argv.items, gpa);
1748 defer child.deinit();
1746 if (std.builtin.os.tag != .windows and arg_mode == .run and !watch) {
1747 var env_vars = try process.getEnvMap(gpa);
1748 const err = os.execvpe(gpa, argv.items, &env_vars);
1749 env_vars.deinit(); // it would cause a memory leak because a defer would be unreachable because of fatal
1750 fatal("There was an error with `zig run`: {}", .{@errorName(err)});
1751 } else {
1752 const child = try std.ChildProcess.init(argv.items, gpa);
1753 defer child.deinit();
17491754
1750 child.stdin_behavior = .Inherit;
1751 child.stdout_behavior = .Inherit;
1752 child.stderr_behavior = .Inherit;
1755 child.stdin_behavior = .Inherit;
1756 child.stdout_behavior = .Inherit;
1757 child.stderr_behavior = .Inherit;
17531758
1754 const term = try child.spawnAndWait();
1755 switch (arg_mode) {
1756 .run => {
1757 switch (term) {
1758 .Exited => |code| {
1759 if (code == 0) {
1760 if (!watch) return cleanExit();
1761 } else {
1762 // TODO https://github.com/ziglang/zig/issues/6342
1763 process.exit(1);
1764 }
1765 },
1766 else => process.exit(1),
1767 }
1768 },
1769 .zig_test => {
1770 switch (term) {
1771 .Exited => |code| {
1772 if (code == 0) {
1773 if (!watch) return cleanExit();
1774 } else {
1759 const term = try child.spawnAndWait();
1760 switch (arg_mode) {
1761 .run => {
1762 switch (term) {
1763 .Exited => |code| {
1764 if (code == 0) {
1765 if (!watch) return cleanExit();
1766 } else {
1767 // TODO https://github.com/ziglang/zig/issues/6342
1768 process.exit(1);
1769 }
1770 },
1771 else => process.exit(1),
1772 }
1773 },
1774 .zig_test => {
1775 switch (term) {
1776 .Exited => |code| {
1777 if (code == 0) {
1778 if (!watch) return cleanExit();
1779 } else {
1780 const cmd = try argvCmd(arena, argv.items);
1781 fatal("the following test command failed with exit code {}:\n{}", .{ code, cmd });
1782 }
1783 },
1784 else => {
17751785 const cmd = try argvCmd(arena, argv.items);
1776 fatal("the following test command failed with exit code {}:\n{}", .{ code, cmd });
1777 }
1778 },
1779 else => {
1780 const cmd = try argvCmd(arena, argv.items);
1781 fatal("the following test command crashed:\n{}", .{cmd});
1782 },
1783 }
1784 },
1785 else => unreachable,
1786 fatal("the following test command crashed:\n{}", .{cmd});
1787 },
1788 }
1789 },
1790 else => unreachable,
1791 }
17861792 }
17871793 },
17881794 else => {},