diff options
Diffstat (limited to 'src/executor.zig')
| -rw-r--r-- | src/executor.zig | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/executor.zig b/src/executor.zig index cdddb4f..02ec159 100644 --- a/src/executor.zig +++ b/src/executor.zig @@ -103,3 +103,62 @@ pub fn runExternalProgramWithRedirect(allocator: std.mem.Allocator, program_path _ = std.posix.waitpid(pid, 0); } } + +pub fn runExternalPipeline(allocator: std.mem.Allocator, program1_path: []const u8, argv1: []const []const u8, program2_path: []const u8, argv2: []const []const u8) !void { + const argv1_z = try allocator.allocSentinel(?[*:0]const u8, argv1.len, null); + defer allocator.free(argv1_z); + for (argv1, 0..) |arg, i| { + argv1_z[i] = (try allocator.dupeZ(u8, arg)).ptr; + } + defer { + for (argv1_z[0..argv1.len]) |arg_ptr| { + if (arg_ptr) |ptr| allocator.free(std.mem.span(ptr)); + } + } + + const argv2_z = try allocator.allocSentinel(?[*:0]const u8, argv2.len, null); + defer allocator.free(argv2_z); + for (argv2, 0..) |arg, i| { + argv2_z[i] = (try allocator.dupeZ(u8, arg)).ptr; + } + defer { + for (argv2_z[0..argv2.len]) |arg_ptr| { + if (arg_ptr) |ptr| allocator.free(std.mem.span(ptr)); + } + } + + const program1_path_z = try allocator.dupeZ(u8, program1_path); + defer allocator.free(program1_path_z); + const program2_path_z = try allocator.dupeZ(u8, program2_path); + defer allocator.free(program2_path_z); + + const fds = try std.posix.pipe(); + + const pid1 = try std.posix.fork(); + if (pid1 == 0) { + std.posix.close(fds[0]); + try std.posix.dup2(fds[1], 1); + std.posix.close(fds[1]); + _ = std.posix.execveZ(program1_path_z, argv1_z, std.c.environ) catch { + std.posix.exit(1); + }; + unreachable; + } + + const pid2 = try std.posix.fork(); + if (pid2 == 0) { + std.posix.close(fds[1]); + try std.posix.dup2(fds[0], 0); + std.posix.close(fds[0]); + _ = std.posix.execveZ(program2_path_z, argv2_z, std.c.environ) catch { + std.posix.exit(1); + }; + unreachable; + } + + std.posix.close(fds[0]); + std.posix.close(fds[1]); + + _ = std.posix.waitpid(pid1, 0); + _ = std.posix.waitpid(pid2, 0); +} |