Path: blob/main/core/posix-node/scratch/fork.zig
1396 views
// zig run fork.zig12const c = @cImport({3@cInclude("unistd.h");4@cInclude("fcntl.h"); // just needed for constants5@cInclude("grp.h"); // getgrouplist on linux6@cDefine("struct__OSUnalignedU16", "uint16_t");7@cDefine("struct__OSUnalignedU32", "uint32_t");8@cDefine("struct__OSUnalignedU64", "uint64_t");9@cInclude("sys/wait.h");10});11const std = @import("std");12const log = std.debug.print;1314const Errors = error{RuntimeError};1516pub fn main() !void {17var stdin: [2]c_int = undefined;18if (c.pipe(&stdin) == -1) {19return Errors.RuntimeError;20}21log("stdin pipe {any}\n", .{stdin});2223var stdout: [2]c_int = undefined;24if (c.pipe(&stdout) == -1) {25return Errors.RuntimeError;26}27log("stdout pipe {any}\n", .{stdout});2829const pid = c.fork();30if (pid == -1) {31log("fork error\n", .{});32return Errors.RuntimeError;33}34if (pid == 0) {35log("in child process\n", .{});36if (c.dup2(stdin[0], 0) == -1) {37log("dup2 stdin fail\n", .{});38return Errors.RuntimeError;39}40if (c.dup2(stdout[1], 1) == -1) {41log("dup2 stdout fail\n", .{});42return Errors.RuntimeError;43}44if (c.close(stdin[0]) == -1) {45log("failed to close stdin[0] pipe\n", .{});46}47if (c.close(stdin[1]) == -1) {48log("failed to close stdin[1] pipe\n", .{});49}50if (c.close(stdout[0]) == -1) {51log("failed to close stdout[0] pipe\n", .{});52}53if (c.close(stdout[1]) == -1) {54log("failed to close stdout[1] pipe\n", .{});55}5657const len = 1;58var memory = std.c.malloc(@sizeOf(?[*:0]u8) * (len + 1)) orelse {59return Errors.RuntimeError;60};61var aligned = @alignCast(std.meta.alignment([*](?[*:0]u8)), memory);62var s: [*](?[*:0]u8) = @ptrCast([*](?[*:0]u8), aligned);63s[len] = null;64const cmd = "/bin/cat";65s[0] = @ptrCast([*:0]u8, cmd);6667if (c.execv(@ptrCast([*:0]u8, cmd), s) == -1) {68log("failed to execv", .{});69return Errors.RuntimeError;70}71} else {72log("in parent process; child={}\n", .{pid});73if (c.write(stdin[1], "hello", 5) == -1) {74log("failed to write to stdin\n", .{});75return Errors.RuntimeError;76}77if (c.close(stdin[1]) == -1) {78log("failed to close stdin pipe\n", .{});79return Errors.RuntimeError;80}81log("closed stdin\n", .{});82var buf = [_]u8{0} ** 100;83if (c.read(stdout[0], &buf, 5) == -1) {84log("failed to read from stdout\n", .{});85return Errors.RuntimeError;86}87buf[5] = 0;88log("read '{s}' from stdout\n", .{buf});8990var wstatus: c_int = undefined;91const ret = c.waitpid(pid, &wstatus, 0);92if (ret == -1) {93log("error calling waitpid\n", .{});94return Errors.RuntimeError;95}96log("ret = {d}, wstatus = {d}\n", .{ ret, wstatus });97}98}99100101