I am writing something with zig using std.childProcess, like below simplified version
const rr = std.childProcess.run(.{
.allocator = std.testing.allocator,
.argv = &[_][]const u8{
"my-test-external-program"
},
});
Then I have some other code try to log the execution result like below
switch (rr.term) {
.Exited => |ret| {
log_writer.print("Command exit with {d}!", .{ret}) catch {};
},
.Signal => |ret| {
log_writer.print("Command exited with signal {d}! Error!", .{ ret }) catch {};
},
.Stopped => |ret| {
log_writer.print("Command stopped with {d}! Error!", .{ ret }) catch {};
},
.Unknown => |ret| {
log_writer.print("Command exited with unknown reason {d}! Error!", .{ ret }) catch {};
},
}
The key here is to cover all possible cases and also leave something for later log analysis.
Now I need to test my code, and I want to also cover all. For .Exited and .Signal cases are easy, for former I write a testing c program will exit from 0 to 127. For later, I also write a program use raise(SIGXXX) for signals.
The real problem is that I do not know how to test .Stopped and .Unknown. I know it is hard to see them, but still want to somehow test them, or just understand them (for curiosity).
I have read the zig source code, know that the ret code of my program should be something different. So I have tried some exp like
test "try" {
const s: u32 = 0x8f7f;
const ii = @as(u16, @truncate(((s & 0xffff) *% 0x10001) >> 8));
std.debug.print("\n{x} {any} {any}\n", .{ ii, std.os.linux.W.IFEXITED(s), std.os.linux.W.IFSTOPPED(s) });
}
and I can get out like 7f8f false true
, means I can use this code (or make more) to trigger expected behaivor in zig if I can ret them from my c code.
and I write a simple c program like below (which is using aarch64 assembly)
#include <unistd.h>
void main() {
int ret_value = 0x8f7f;
asm volatile(
"mov w0, %w[ret_value]\n" // move ret_value to w0
"mov x16, #0x1\n" // move 0x1 to x16, syscall no. 1 = exit
"svc #0x80\n" // arm64 system call [x16]
"ret"
: [ret_value] "=r"(ret_value) // Input operand constraint for the variable
// : // No output operand constraints
// : "x16" // List of clobbered registers
);
}
but I will never get zig side to get the 0x8f7f ret code, in face, as I debug from child_process.zig:418, shows, when I return 0x8f7f, the os.waitpid get is 0x7f00, which I can not understand.
try my luck here see whether someone knows how to get this part done, for my curiosity I thank you in advance.