authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2022-04-29 17:07:51+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-29 22:50:34-04:00
loga0a2ce92ca129d28e22c63f7bace1672c43776b5
tree26bb1adc15b8dcc3aae1e38a4d57800d7319b030
parent0e49142ce478c13f3ec701900cd894b3536471a1

std: Do not allocate the result for ChildProcess.init

Instead, just return ChildProcess directly. This structure does not require a stable address, so we can put it on the stack just fine. If someone wants it on the heap they should do. const proc = try allocator.create(ChildProcess); proc.* = ChildProcess.init(args, allocator);

11 files changed, 21 insertions(+), 54 deletions(-)

lib/std/build.zig+2-6
......@@ -971,9 +971,7 @@ pub const Builder = struct {
971971 if (!std.process.can_spawn)
972972 return error.ExecNotSupported;
973973
974 const child = std.ChildProcess.init(argv, self.allocator) catch unreachable;
975 defer child.deinit();
976
974 var child = std.ChildProcess.init(argv, self.allocator);
977975 child.cwd = cwd;
978976 child.env_map = env_map;
979977
......@@ -1187,9 +1185,7 @@ pub const Builder = struct {
11871185 return error.ExecNotSupported;
11881186
11891187 const max_output_size = 400 * 1024;
1190 const child = try std.ChildProcess.init(argv, self.allocator);
1191 defer child.deinit();
1192
1188 var child = std.ChildProcess.init(argv, self.allocator);
11931189 child.stdin_behavior = .Ignore;
11941190 child.stdout_behavior = .Pipe;
11951191 child.stderr_behavior = stderr_behavior;
lib/std/build/RunStep.zig+1-3
......@@ -184,9 +184,7 @@ fn make(step: *Step) !void {
184184 return ExecError.ExecNotSupported;
185185 }
186186
187 const child = std.ChildProcess.init(argv, self.builder.allocator) catch unreachable;
188 defer child.deinit();
189
187 var child = std.ChildProcess.init(argv, self.builder.allocator);
190188 child.cwd = cwd;
191189 child.env_map = self.env_map orelse self.builder.env_map;
192190
lib/std/child_process.zig+7-19
......@@ -98,10 +98,8 @@ pub const ChildProcess = struct {
9898 };
9999
100100 /// First argument in argv is the executable.
101 /// On success must call deinit.
102 pub fn init(argv: []const []const u8, allocator: mem.Allocator) !*ChildProcess {
103 const child = try allocator.create(ChildProcess);
104 child.* = ChildProcess{
101 pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess {
102 return .{
105103 .allocator = allocator,
106104 .argv = argv,
107105 .pid = undefined,
......@@ -121,8 +119,6 @@ pub const ChildProcess = struct {
121119 .stderr_behavior = StdIo.Inherit,
122120 .expand_arg0 = .no_expand,
123121 };
124 errdefer allocator.destroy(child);
125 return child;
126122 }
127123
128124 pub fn setUserName(self: *ChildProcess, name: []const u8) !void {
......@@ -199,7 +195,7 @@ pub const ChildProcess = struct {
199195 };
200196
201197 fn collectOutputPosix(
202 child: *const ChildProcess,
198 child: ChildProcess,
203199 stdout: *std.ArrayList(u8),
204200 stderr: *std.ArrayList(u8),
205201 max_output_bytes: usize,
......@@ -298,7 +294,7 @@ pub const ChildProcess = struct {
298294 }
299295 }
300296
301 fn collectOutputWindows(child: *const ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
297 fn collectOutputWindows(child: ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
302298 const bump_amt = 512;
303299 const handles = [_]windows.HANDLE{
304300 child.stdout.?.handle,
......@@ -383,9 +379,7 @@ pub const ChildProcess = struct {
383379 max_output_bytes: usize = 50 * 1024,
384380 expand_arg0: Arg0Expand = .no_expand,
385381 }) !ExecResult {
386 const child = try ChildProcess.init(args.argv, args.allocator);
387 defer child.deinit();
388
382 var child = ChildProcess.init(args.argv, args.allocator);
389383 child.stdin_behavior = .Ignore;
390384 child.stdout_behavior = .Pipe;
391385 child.stderr_behavior = .Pipe;
......@@ -452,10 +446,6 @@ pub const ChildProcess = struct {
452446 return self.term.?;
453447 }
454448
455 pub fn deinit(self: *ChildProcess) void {
456 self.allocator.destroy(self);
457 }
458
459449 fn waitUnwrappedWindows(self: *ChildProcess) !void {
460450 const result = windows.WaitForSingleObjectEx(self.handle, windows.INFINITE, false);
461451
......@@ -1374,8 +1364,7 @@ test "build and call child_process" {
13741364
13751365 // spawn compiled file as child_process with argument 'hello world' + expect success
13761366 const args = [_][]const u8{ child_path, "hello world" };
1377 var child_proc = try ChildProcess.init(&args, allocator);
1378 defer child_proc.deinit();
1367 var child_proc = ChildProcess.init(&args, allocator);
13791368 const ret_val = try child_proc.spawnAndWait();
13801369 try testing.expectEqual(ret_val, .{ .Exited = 0 });
13811370}
......@@ -1385,11 +1374,10 @@ test "creating a child process with stdin and stdout behavior set to StdIo.Pipe"
13851374 const testing = std.testing;
13861375 const allocator = testing.allocator;
13871376
1388 var child_process = try std.ChildProcess.init(
1377 var child_process = std.ChildProcess.init(
13891378 &[_][]const u8{ testing.zig_exe_path, "fmt", "--stdin" },
13901379 allocator,
13911380 );
1392 defer child_process.deinit();
13931381 child_process.stdin_behavior = .Pipe;
13941382 child_process.stdout_behavior = .Pipe;
13951383
lib/std/testing.zig+3-2
......@@ -442,10 +442,11 @@ pub fn buildExe(zigexec: []const u8, zigfile: []const u8, binfile: []const u8) !
442442 const flag_emit = "-femit-bin=";
443443 const cmd_emit = try std.mem.concat(allocator, u8, &[_][]const u8{ flag_emit, binfile });
444444 defer allocator.free(cmd_emit);
445
445446 const args = [_][]const u8{ zigexec, "build-exe", zigfile, cmd_emit };
446 var procCompileChild = try std.ChildProcess.init(&args, allocator);
447 defer procCompileChild.deinit();
447 var procCompileChild = std.ChildProcess.init(&args, allocator);
448448 try procCompileChild.spawn();
449
449450 const ret_val = try procCompileChild.wait();
450451 try expectEqual(ret_val, .{ .Exited = 0 });
451452}
src/Compilation.zig+1-3
......@@ -3611,9 +3611,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
36113611 }
36123612
36133613 if (std.process.can_spawn) {
3614 const child = try std.ChildProcess.init(argv.items, arena);
3615 defer child.deinit();
3616
3614 var child = std.ChildProcess.init(argv.items, arena);
36173615 if (comp.clang_passthrough_mode) {
36183616 child.stdin_behavior = .Inherit;
36193617 child.stdout_behavior = .Inherit;
src/link/Coff.zig+1-3
......@@ -1390,9 +1390,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
13901390 // If possible, we run LLD as a child process because it does not always
13911391 // behave properly as a library, unfortunately.
13921392 // https://github.com/ziglang/zig/issues/3825
1393 const child = try std.ChildProcess.init(argv.items, arena);
1394 defer child.deinit();
1395
1393 var child = std.ChildProcess.init(argv.items, arena);
13961394 if (comp.clang_passthrough_mode) {
13971395 child.stdin_behavior = .Inherit;
13981396 child.stdout_behavior = .Inherit;
src/link/Elf.zig+1-3
......@@ -1754,9 +1754,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
17541754 // If possible, we run LLD as a child process because it does not always
17551755 // behave properly as a library, unfortunately.
17561756 // https://github.com/ziglang/zig/issues/3825
1757 const child = try std.ChildProcess.init(argv.items, arena);
1758 defer child.deinit();
1759
1757 var child = std.ChildProcess.init(argv.items, arena);
17601758 if (comp.clang_passthrough_mode) {
17611759 child.stdin_behavior = .Inherit;
17621760 child.stdout_behavior = .Inherit;
src/link/Wasm.zig+1-3
......@@ -2405,9 +2405,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
24052405 // If possible, we run LLD as a child process because it does not always
24062406 // behave properly as a library, unfortunately.
24072407 // https://github.com/ziglang/zig/issues/3825
2408 const child = try std.ChildProcess.init(argv.items, arena);
2409 defer child.deinit();
2410
2408 var child = std.ChildProcess.init(argv.items, arena);
24112409 if (comp.clang_passthrough_mode) {
24122410 child.stdin_behavior = .Inherit;
24132411 child.stdout_behavior = .Inherit;
src/main.zig+2-6
......@@ -3012,9 +3012,7 @@ fn runOrTest(
30123012 const cmd = try std.mem.join(arena, " ", argv.items);
30133013 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
30143014 } else if (std.process.can_spawn) {
3015 const child = try std.ChildProcess.init(argv.items, gpa);
3016 defer child.deinit();
3017
3015 var child = std.ChildProcess.init(argv.items, gpa);
30183016 child.stdin_behavior = .Inherit;
30193017 child.stdout_behavior = .Inherit;
30203018 child.stderr_behavior = .Inherit;
......@@ -3700,9 +3698,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
37003698 };
37013699
37023700 if (std.process.can_spawn) {
3703 const child = try std.ChildProcess.init(child_argv, gpa);
3704 defer child.deinit();
3705
3701 var child = std.ChildProcess.init(child_argv, gpa);
37063702 child.stdin_behavior = .Inherit;
37073703 child.stdout_behavior = .Inherit;
37083704 child.stderr_behavior = .Inherit;
src/mingw.zig+1-3
......@@ -369,9 +369,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
369369 }
370370
371371 if (std.process.can_spawn) {
372 const child = try std.ChildProcess.init(&args, arena);
373 defer child.deinit();
374
372 var child = std.ChildProcess.init(&args, arena);
375373 child.stdin_behavior = .Ignore;
376374 child.stdout_behavior = .Pipe;
377375 child.stderr_behavior = .Pipe;
test/tests.zig+1-3
......@@ -731,9 +731,7 @@ pub const StackTracesContext = struct {
731731 return ExecError.ExecNotSupported;
732732 }
733733
734 const child = std.ChildProcess.init(args.items, b.allocator) catch unreachable;
735 defer child.deinit();
736
734 var child = std.ChildProcess.init(args.items, b.allocator);
737735 child.stdin_behavior = .Ignore;
738736 child.stdout_behavior = .Pipe;
739737 child.stderr_behavior = .Pipe;