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");...@@ -2,6 +2,7 @@ const std = @import("std");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const io = std.io;3const io = std.io;
4const fs = std.fs;4const fs = std.fs;
5const os = std.os;
5const mem = std.mem;6const mem = std.mem;
6const process = std.process;7const process = std.process;
7const Allocator = mem.Allocator;8const Allocator = mem.Allocator;
...@@ -1742,47 +1743,52 @@ fn buildOutputType(...@@ -1742,47 +1743,52 @@ fn buildOutputType(
1742 if (runtime_args_start) |i| {1743 if (runtime_args_start) |i| {
1743 try argv.appendSlice(all_args[i..]);1744 try argv.appendSlice(all_args[i..]);
1744 }1745 }
1745 // TODO On operating systems that support it, do an execve here rather than child process,1746 if (std.builtin.os.tag != .windows and arg_mode == .run and !watch) {
1746 // when watch=false and arg_mode == .run1747 var env_vars = try process.getEnvMap(gpa);
1747 const child = try std.ChildProcess.init(argv.items, gpa);1748 const err = os.execvpe(gpa, argv.items, &env_vars);
1748 defer child.deinit();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;1755 child.stdin_behavior = .Inherit;
1751 child.stdout_behavior = .Inherit;1756 child.stdout_behavior = .Inherit;
1752 child.stderr_behavior = .Inherit;1757 child.stderr_behavior = .Inherit;
17531758
1754 const term = try child.spawnAndWait();1759 const term = try child.spawnAndWait();
1755 switch (arg_mode) {1760 switch (arg_mode) {
1756 .run => {1761 .run => {
1757 switch (term) {1762 switch (term) {
1758 .Exited => |code| {1763 .Exited => |code| {
1759 if (code == 0) {1764 if (code == 0) {
1760 if (!watch) return cleanExit();1765 if (!watch) return cleanExit();
1761 } else {1766 } else {
1762 // TODO https://github.com/ziglang/zig/issues/63421767 // TODO https://github.com/ziglang/zig/issues/6342
1763 process.exit(1);1768 process.exit(1);
1764 }1769 }
1765 },1770 },
1766 else => process.exit(1),1771 else => process.exit(1),
1767 }1772 }
1768 },1773 },
1769 .zig_test => {1774 .zig_test => {
1770 switch (term) {1775 switch (term) {
1771 .Exited => |code| {1776 .Exited => |code| {
1772 if (code == 0) {1777 if (code == 0) {
1773 if (!watch) return cleanExit();1778 if (!watch) return cleanExit();
1774 } else {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 => {
1775 const cmd = try argvCmd(arena, argv.items);1785 const cmd = try argvCmd(arena, argv.items);
1776 fatal("the following test command failed with exit code {}:\n{}", .{ code, cmd });1786 fatal("the following test command crashed:\n{}", .{cmd});
1777 }1787 },
1778 },1788 }
1779 else => {1789 },
1780 const cmd = try argvCmd(arena, argv.items);1790 else => unreachable,
1781 fatal("the following test command crashed:\n{}", .{cmd});1791 }
1782 },
1783 }
1784 },
1785 else => unreachable,
1786 }1792 }
1787 },1793 },
1788 else => {},1794 else => {},