From 85a07116af34d6786afad4d833c49dc754010b41 Mon Sep 17 00:00:00 2001 From: Pascal Zittlau Date: Mon, 15 Dec 2025 15:59:04 +0100 Subject: [PATCH] fork test --- src/main.zig | 19 +++++++++++++++++++ src/syscalls.zig | 4 ---- src/test/fork.zig | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/test/fork.zig diff --git a/src/main.zig b/src/main.zig index d0b16e6..016b8bc 100644 --- a/src/main.zig +++ b/src/main.zig @@ -356,6 +356,25 @@ test "echo" { try testHelper(&.{ "echo", "Hello", "There" }, "Hello There\n"); } +test "nolibc_nopie_fork" { + try testHelper( + &.{ flicker_path, getTestExePath("nolibc_nopie_fork") }, + "Child: I'm alive!\nParent: Child died.\n", + ); +} +test "nolibc_pie_fork" { + try testHelper( + &.{ flicker_path, getTestExePath("nolibc_pie_fork") }, + "Child: I'm alive!\nParent: Child died.\n", + ); +} +test "libc_pie_fork" { + try testHelper( + &.{ flicker_path, getTestExePath("libc_pie_fork") }, + "Child: I'm alive!\nParent: Child died.\n", + ); +} + fn testPrintArgs(comptime name: []const u8) !void { const exe_path = getTestExePath(name); const loader_argv: []const []const u8 = &.{ flicker_path, exe_path, "foo", "bar", "baz hi" }; diff --git a/src/syscalls.zig b/src/syscalls.zig index a577dc9..8c4110d 100644 --- a/src/syscalls.zig +++ b/src/syscalls.zig @@ -63,10 +63,6 @@ export fn syscall_handler(regs: *UserRegs) callconv(.c) void { std.debug.print("back in `syscall_handler`\n", .{}); return; }, - .fork, .vfork => { - // fork/vfork duplicate the stack (or share it until exec), so the return path via - // syscall_entry works fine. - }, .rt_sigreturn => { @panic("sigreturn is not supported yet"); }, diff --git a/src/test/fork.zig b/src/test/fork.zig new file mode 100644 index 0000000..e13db94 --- /dev/null +++ b/src/test/fork.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const linux = std.os.linux; + +pub fn main() !void { + const ret = linux.syscall0(.fork); + const pid: i32 = @intCast(ret); + + if (pid == 0) { + // --- Child --- + const msg = "Child: I'm alive!\n"; + _ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len); + linux.exit(0); + } else if (pid > 0) { + // --- Parent --- + var status: u32 = 0; + _ = linux.syscall4(.wait4, @intCast(pid), @intFromPtr(&status), 0, 0); + const msg = "Parent: Child died.\n"; + _ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len); + } else { + const msg = "Fork failed!\n"; + _ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len); + } +}