Last active
December 31, 2021 22:50
-
-
Save mtortonesi/933d5a6c601eeaabdccf0bd6fd1ec89c to your computer and use it in GitHub Desktop.
This file contains 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"); | |
pub const io_mode = .evented; | |
const ArgStruct = struct { | |
// Apparently, the following two lines do not compile because of https://github.com/ziglang/zig/issues/10184 | |
// (also see https://github.com/ziglang/zig/pull/4567 and https://github.com/ziglang/zig/issues/1268) | |
// in: *@TypeOf(std.io.Reader), | |
// out: *@TypeOf(std.io.Writer), | |
// Apparently, the following two lines do not compile because of https://github.com/ziglang/zig/issues/5877 | |
in: anytype, | |
out: anytype, | |
buf: []u8, | |
loop: std.event.Loop, | |
alloc: std.mem.Allocator, | |
}; | |
pub fn main() !void { | |
// Shortcut to standard input and output | |
const stdin = std.io.getStdIn().reader(); | |
const stdout = std.io.getStdOut().writer(); | |
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | |
const alloc = gpa.allocator(); | |
// Create iterator on argument vector | |
var arg_it = std.process.args(); | |
defer arg_it.deinit(); | |
_ = arg_it.skip(); // skip name of executable | |
var hostname = try getNextArg(&arg_it, alloc) orelse { | |
std.debug.print("Expected first argument to be the hostname\n", .{}); | |
return error.InvalidArgs; | |
}; | |
var port = try getNextArg(&arg_it, alloc) orelse { | |
std.debug.print("Expected second argument to be the port\n", .{}); | |
return error.InvalidArgs; | |
}; | |
var port_number = try std.fmt.parseInt(u16, port, 10); | |
var sockStream = try std.net.tcpConnectToHost(alloc, hostname, port_number); | |
var netIn = sockStream.reader(); | |
var netOut = sockStream.writer(); | |
var buf1: [4096]u8 = undefined; | |
var buf2: [4096]u8 = undefined; | |
var loop: std.event.Loop = undefined; | |
try loop.initMultiThreaded(); | |
defer loop.deinit(); | |
try loop.runDetached(alloc, readAndForward, ArgStruct{ .in = netIn, .out = stdout, .buf = &buf1, .loop = loop, .allocator = alloc }); | |
try loop.runDetached(alloc, readAndForward, ArgStruct{ .in = &stdin, .out = &netOut, .buf = &buf2, .loop = loop, .allocator = alloc }); | |
loop.run(); | |
return; | |
} | |
// See https://github.com/ziglang/zig/issues/6515 | |
fn getNextArg(arg_it: *std.process.ArgIterator, allocator: std.mem.Allocator) ?anyerror![]u8 { | |
var arg = arg_it.next(allocator); | |
return @as(?anyerror![]u8, arg); | |
} | |
fn readAndForward(comptime args: ArgStruct) !void { | |
// read into buffer | |
var bytesRead = try args.in.read(args.buf); | |
// write buffer content into output | |
try args.out.write(args.buf[0..bytesRead]); | |
// re-register itself | |
// try args.loop.runDetached(args.allocator, readAndForward, .{ .in = args.in, .out = args.out, .buf = args.buf, .loop = args.loop, .allocator = args.allocator }); | |
try args.loop.runDetached(args.allocator, readAndForward, args); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment