forked from ziglang/zig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
std.child_process: enable non-standard streams
This PR simplifies the setup code and handling of non-standard file descriptors and handles for Windows and Posix with main focus on pipes. Portable pipes default to pipe2 with CLOEXEC on Posix and disabled handle inhertance on Windows except shortly before and after the creation of the "child process". Leaking of file desriptors on Posix 1. CLOEXEC does not take immediately effect with clone(), but after the setup code for the child process was run and a exec* function is executed. External code may at worst be long living and never do exec*. 2. File descriptors without CLOEXEC are designed to "leak to the child", but every spawned process at the same time gets them as well. Leaking of handles on Windows 1. File leaking on Windows can be fixed with an explicit list approach as suggested in ziglang#14251, which might require runtime probing and allocation of the necessary process setup list. Otherwise, it might break on Kernel updates. 2. The potential time for leaking can be long due trying to spawn on multiple PATH and PATHEXT entries on Windows.
- Loading branch information
Showing
9 changed files
with
285 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const Builder = @import("std").build.Builder; | ||
|
||
pub fn build(b: *Builder) void { | ||
const target = b.standardTargetOptions(.{}); | ||
const optimize = b.standardOptimizeOption(.{}); | ||
|
||
const child = b.addExecutable(.{ | ||
.name = "child", | ||
.root_source_file = .{ .path = "child.zig" }, | ||
.target = target, | ||
.optimize = optimize, | ||
}); | ||
|
||
const parent = b.addExecutable(.{ | ||
.name = "parent", | ||
.root_source_file = .{ .path = "parent.zig" }, | ||
.target = target, | ||
.optimize = optimize, | ||
}); | ||
const run_cmd = parent.run(); | ||
run_cmd.addArtifactArg(child); | ||
|
||
const test_step = b.step("test", "Test it"); | ||
test_step.dependOn(&run_cmd.step); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const std = @import("std"); | ||
const builtin = @import("builtin"); | ||
const windows = std.os.windows; | ||
pub fn main() !void { | ||
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; | ||
defer if (general_purpose_allocator.deinit()) @panic("found memory leaks"); | ||
const gpa = general_purpose_allocator.allocator(); | ||
|
||
var it = try std.process.argsWithAllocator(gpa); | ||
defer it.deinit(); | ||
_ = it.next() orelse unreachable; // skip binary name | ||
const s_handle = it.next() orelse unreachable; | ||
var file_handle = try std.os.stringToHandle(s_handle); | ||
defer std.os.close(file_handle); | ||
|
||
// child inherited the handle, so inheritance must be enabled | ||
const is_inheritable = try std.os.isInheritable(file_handle); | ||
std.debug.assert(is_inheritable); | ||
|
||
try std.os.disableInheritance(file_handle); | ||
var file_in = std.fs.File{ .handle = file_handle }; // read side of pipe | ||
const file_in_reader = file_in.reader(); | ||
const message = try file_in_reader.readUntilDelimiterAlloc(gpa, '\x17', 20_000); | ||
defer gpa.free(message); | ||
try std.testing.expectEqualSlices(u8, message, "test123"); | ||
} |
Oops, something went wrong.