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