authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-15 16:03:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-15 16:03:32-04:00
logbb169a7b36a658ed463787655df54e3f59133d98
tree773587c8f8d31ff2d892d37ad8bcc3f6e1d319a5
parent1fe1e6eeaf2f6157133546d49be6b0e0c1da3dd3

fix child process stdio piping behavior on windows


4 files changed, 22 insertions(+), 17 deletions(-)

std/io.zig+1-1
......@@ -313,8 +313,8 @@ pub const InStream = struct {
313313 else => error.Unexpected,
314314 };
315315 }
316 if (amt_read == 0) return index;
317316 index += amt_read;
317 if (amt_read < want_read_count) return index;
318318 }
319319 return index;
320320 } else {
std/os/child_process.zig+14-7
......@@ -433,7 +433,7 @@ pub const ChildProcess = struct {
433433 }
434434
435435 fn spawnWindows(self: &ChildProcess) -> %void {
436 var saAttr = windows.SECURITY_ATTRIBUTES {
436 const saAttr = windows.SECURITY_ATTRIBUTES {
437437 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
438438 .bInheritHandle = windows.TRUE,
439439 .lpSecurityDescriptor = null,
......@@ -459,7 +459,7 @@ pub const ChildProcess = struct {
459459 var g_hChildStd_IN_Wr: ?windows.HANDLE = null;
460460 switch (self.stdin_behavior) {
461461 StdIo.Pipe => {
462 %return windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr);
462 %return windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr);
463463 },
464464 StdIo.Ignore => {
465465 g_hChildStd_IN_Rd = nul_handle;
......@@ -477,7 +477,7 @@ pub const ChildProcess = struct {
477477 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
478478 switch (self.stdout_behavior) {
479479 StdIo.Pipe => {
480 %return windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr);
480 %return windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr);
481481 },
482482 StdIo.Ignore => {
483483 g_hChildStd_OUT_Wr = nul_handle;
......@@ -495,7 +495,7 @@ pub const ChildProcess = struct {
495495 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
496496 switch (self.stderr_behavior) {
497497 StdIo.Pipe => {
498 %return windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr);
498 %return windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr);
499499 },
500500 StdIo.Ignore => {
501501 g_hChildStd_ERR_Wr = nul_handle;
......@@ -675,7 +675,12 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {
675675 if (wr) |h| os.windowsClose(h);
676676}
677677
678fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &windows.SECURITY_ATTRIBUTES) -> %void {
678
679// TODO: workaround for bug where the `const` from `&const` is dropped when the type is
680// a namespace field lookup
681const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
682
683fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {
679684 if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {
680685 const err = windows.GetLastError();
681686 return switch (err) {
......@@ -693,19 +698,21 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
693698 }
694699}
695700
696fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &windows.SECURITY_ATTRIBUTES) -> %void {
701fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {
697702 var rd_h: windows.HANDLE = undefined;
698703 var wr_h: windows.HANDLE = undefined;
699704 %return windowsMakePipe(&rd_h, &wr_h, sattr);
705 %defer windowsDestroyPipe(rd_h, wr_h);
700706 %return windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
701707 *rd = rd_h;
702708 *wr = wr_h;
703709}
704710
705fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &windows.SECURITY_ATTRIBUTES) -> %void {
711fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {
706712 var rd_h: windows.HANDLE = undefined;
707713 var wr_h: windows.HANDLE = undefined;
708714 %return windowsMakePipe(&rd_h, &wr_h, sattr);
715 %defer windowsDestroyPipe(rd_h, wr_h);
709716 %return windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
710717 *rd = rd_h;
711718 *wr = wr_h;
std/os/windows/index.zig+1-1
......@@ -18,7 +18,7 @@ pub extern "kernel32" stdcallcc fn CreateFileA(lpFileName: LPCSTR, dwDesiredAcce
1818 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) -> HANDLE;
1919
2020pub extern "kernel32" stdcallcc fn CreatePipe(hReadPipe: &HANDLE, hWritePipe: &HANDLE,
21 lpPipeAttributes: &SECURITY_ATTRIBUTES, nSize: DWORD) -> BOOL;
21 lpPipeAttributes: &const SECURITY_ATTRIBUTES, nSize: DWORD) -> BOOL;
2222
2323pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,
2424 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,
test/tests.zig+6-8
......@@ -557,7 +557,7 @@ pub const CompileErrorContext = struct {
557557 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
558558
559559 if (b.verbose) {
560 printInvocation(b.zig_exe, zig_args.toSliceConst());
560 printInvocation(zig_args.toSliceConst());
561561 }
562562
563563 const child = %%os.ChildProcess.init(zig_args.toSliceConst(), b.allocator);
......@@ -625,10 +625,9 @@ pub const CompileErrorContext = struct {
625625 }
626626 };
627627
628 fn printInvocation(exe_path: []const u8, args: []const []const u8) {
629 %%io.stderr.printf("{}", exe_path);
628 fn printInvocation(args: []const []const u8) {
630629 for (args) |arg| {
631 %%io.stderr.printf(" {}", arg);
630 %%io.stderr.printf("{} ", arg);
632631 }
633632 %%io.stderr.printf("\n");
634633 }
......@@ -826,7 +825,7 @@ pub const ParseCContext = struct {
826825 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
827826
828827 if (b.verbose) {
829 printInvocation(b.zig_exe, zig_args.toSliceConst());
828 printInvocation(zig_args.toSliceConst());
830829 }
831830
832831 const child = %%os.ChildProcess.init(zig_args.toSliceConst(), b.allocator);
......@@ -895,10 +894,9 @@ pub const ParseCContext = struct {
895894 }
896895 };
897896
898 fn printInvocation(exe_path: []const u8, args: []const []const u8) {
899 %%io.stderr.printf("{}", exe_path);
897 fn printInvocation(args: []const []const u8) {
900898 for (args) |arg| {
901 %%io.stderr.printf(" {}", arg);
899 %%io.stderr.printf("{} ", arg);
902900 }
903901 %%io.stderr.printf("\n");
904902 }