Last active
March 4, 2022 15:29
-
-
Save matu3ba/dbcead4e15291cb57abba78994dbefba to your computer and use it in GitHub Desktop.
parentchild_pipe on Windows naively ported to Zig
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", .{}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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