Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Last active March 7, 2022 00:21
Show Gist options
  • Save matu3ba/0add09568327bad64e7181f9faadca40 to your computer and use it in GitHub Desktop.
Save matu3ba/0add09568327bad64e7181f9faadca40 to your computer and use it in GitHub Desktop.
write+compile child executable and call it as subprocess in Zig with checks
const std = @import("std");
const childstr =
\\ const std = @import("std");
\\ const builtin = @import("builtin");
\\ const os = std.os;
\\ pub fn main() !void {
\\ var arena_inst = std.heap.ArenaAllocator.init(std.heap.page_allocator);
\\ defer arena_inst.deinit();
\\ const arena = arena_inst.allocator();
\\ var it = try std.process.argsWithAllocator(arena);
\\ defer it.deinit(); // no-op unless WASI or Windows
\\ const prog_name = it.next() orelse unreachable;
\\ const expected_suffix = switch (builtin.os.tag) {
\\ .wasi => "child.wasm",
\\ .windows => "child.exe",
\\ else => "child",
\\ };
\\ const given_suffix = std.fs.path.basename(prog_name);
\\ try std.testing.expect(std.mem.eql(u8, expected_suffix, given_suffix));
\\ const input = it.next() orelse unreachable;
\\ var expect_helloworld = "hello world".*;
\\ try std.testing.expect(std.mem.eql(u8, &expect_helloworld, input));
\\ const stdout = std.io.getStdOut();
\\ const stderr = std.io.getStdErr();
\\ try stdout.writeAll("stdout:");
\\ try stdout.writeAll(input);
\\ try stdout.writeAll("\n");
\\ try stderr.writeAll("stdout:");
\\ try stderr.writeAll(input);
\\ try stdout.writeAll("\n");
\\ }
;
pub fn main() anyerror!void {
var arena_inst = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_inst.deinit();
const arena = arena_inst.allocator();
var tmp = std.testing.tmpDir(.{}); // ie zig-cache/tmp/8DLgoSEqz593PAEE
defer tmp.cleanup();
const exited: []const u8 = "Exited";
const cache = "zig-cache";
const tmpdir = "tmp";
const child_name = "child"; // TODO adjust for windows
const suffix_zig = ".zig";
const child_path = try std.fs.path.join(arena, &[_][]const u8{ cache, tmpdir, &tmp.sub_path, child_name });
defer arena.free(child_path);
const child_zig = try std.mem.concat(arena, u8, &[_][]const u8{ child_path, suffix_zig });
defer arena.free(child_zig);
std.debug.print("child_zig: {s}\n", .{child_zig});
const emit_flag = "-femit-bin=";
const emit_bin = try std.mem.concat(arena, u8, &[_][]const u8{ emit_flag, child_path });
defer arena.free(emit_bin);
std.debug.print("emit_bin: {s}\n", .{emit_bin});
{
// compile file => run 'zig build-exe path/to/child.zig -femit-bin=path/to/child' and expect success
try tmp.dir.writeFile("child.zig", childstr);
const args = [_][]const u8{ "zig", "build-exe", child_zig, emit_bin };
var procCompileChild = try std.ChildProcess.init(&args, arena);
defer procCompileChild.deinit();
std.debug.print("Running command: {s}\n", .{args});
try procCompileChild.spawn();
const ret_val = try procCompileChild.wait();
try std.testing.expectEqualSlices(u8, exited, std.meta.tagName(ret_val));
try std.testing.expectEqual(@as(u8, 0), ret_val.Exited);
}
{
// spawn compiled file as child_process
const args = [_][]const u8{ child_path, "hello world" };
var child_proc = try std.ChildProcess.init(&args, arena);
defer child_proc.deinit();
std.debug.print("Running command: {s}\n", .{args});
try child_proc.spawn();
const ret_val = try child_proc.wait();
try std.testing.expectEqualSlices(u8, exited, std.meta.tagName(ret_val));
try std.testing.expectEqual(@as(u8, 0), ret_val.Exited);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment