Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Last active March 4, 2022 15:29
Show Gist options
  • Save matu3ba/dbcead4e15291cb57abba78994dbefba to your computer and use it in GitHub Desktop.
Save matu3ba/dbcead4e15291cb57abba78994dbefba to your computer and use it in GitHub Desktop.
parentchild_pipe on Windows naively ported to Zig
const std = @import("std");
const os = std.os;
pub fn main() !void {
const buf_size = 25;
var rd_h = os.windows.HANDLE;
var buf: [buf_size]u8 = undefined;
var read: os.windows.DWORD = undefined;
rd_h = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);
if (try os.windows.ReadFile(rd_h, buf, buf_size, &read, null)) {
std.debug.print("child read {d}", .{buf});
} else {
std.debug.print("error reading from pipe", .{});
}
}
const std = @import("std");
const os = std.os;
pub fn main() !void {
var rd_h: os.windows.HANDLE = undefined;
var wr_h: os.windows.HANDLE = undefined;
// docs show zeroing out of startup and process information
// https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/ProcThread/creating-processes.md
var si = os.windows.STARTUPINFOW{
.cb = @sizeOf(os.windows.STARTUPINFOW),
.hStdError = null,
.hStdOutput = null,
.hStdInput = null,
.dwFlags = os.windows.STARTF_USESTDHANDLES,
.lpReserved = null,
.lpDesktop = null,
.lpTitle = null,
.dwX = 0,
.dwY = 0,
.dwXSize = 0,
.dwYSize = 0,
.dwXCountChars = 0,
.dwYCountChars = 0,
.dwFillAttribute = 0,
.wShowWindow = 0,
.cbReserved2 = 0,
.lpReserved2 = null,
};
var pi = os.windows.PROCESS_INFORMATION{
.hProcess = undefined,
.hThread = undefined,
.dwProcessId = 0,
.dwThreadId = 0,
};
const msg: []const u8 = "hello";
// security attributes to allow pipes to be inherited
const sa = os.windows.SECURITY_ATTRIBUTES{
.nLength = @sizeOf(os.windows.SECURITY_ATTRIBUTES),
.lpSecurityDescriptor = null,
.bInheritHandle = os.windows.TRUE,
};
try os.windows.CreatePipe(&rd_h, &wr_h, &sa);
si.hStdOutput = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);
si.hStdInput = rd_h; // redirect stdin to read end of pipe
// replace all handles all of the handles instead of connecting to them
try os.windows.SetHandleInformation(wr_h, os.windows.HANDLE_FLAG_INHERIT, 0);
// create child process (+ erase const)
const child_name: [*:0]const u16 = std.unicode.utf8ToUtf16LeStringLiteral("child.exe");
const ch_n = @intToPtr([*:0]u16, @ptrToInt(child_name));
//const ch_n: [*:0]u16 = @ptrCast([*:0]u16, child_name); @ptrCast can not erase const
//0 for inherit handle
os.windows.CreateProcessW(null, ch_n, null, null, os.windows.TRUE, 0, null, null, &si, &pi) catch |err| {
// TODO(DEBUG): this panics before reaching the panic message due a segfault
std.debug.print("err: {s}", .{@errorName(err)});
@panic("could not create Process");
};
os.windows.CloseHandle(rd_h); // close unused end of pipe
const written: u64 = try os.windows.WriteFile(wr_h, msg, null, std.io.default_mode);
std.debug.assert(written > 0);
//wait for the child process to exit
try os.windows.WaitForSingleObject(pi.hProcess, os.windows.INFINITE);
os.windows.CloseHandle(pi.hProcess);
os.windows.CloseHandle(pi.hThread);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment