summaryrefslogtreecommitdiff
path: root/src/executor.zig
diff options
context:
space:
mode:
authorLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 07:57:40 +0000
committerLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 07:57:40 +0000
commit16c43f33f8f7302a07778153aff59f565592bad8 (patch)
tree87f27926a1c64bcafa0cfc07c89821ef657e8b35 /src/executor.zig
parenteef2bd90f9549858ab61d0bb697906fa1e41a373 (diff)
downloadshell-zig-16c43f33f8f7302a07778153aff59f565592bad8.tar.gz
shell-zig-16c43f33f8f7302a07778153aff59f565592bad8.zip
codecrafters submit [skip ci]
Diffstat (limited to 'src/executor.zig')
-rw-r--r--src/executor.zig59
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);
+}