From 06a01f2b4b5261cb277b29d0f73bc3526b018252 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Fri, 20 Jan 2023 04:04:12 +0100 Subject: [PATCH] Add several example programs. --- zig-impl/other/double-close.zig | 11 ++++ zig-impl/other/example-hexdump.zig | 8 +++ zig-impl/other/rcv-fd.zig | 57 +++++++++++++++++++++ zig-impl/other/snd-fd.zig | 43 ++++++++++++++++ zig-impl/other/test-fn.zig | 25 +++++++++ zig-impl/other/test-tcp-client.zig | 49 ++++++++++++++++++ zig-impl/other/test-tcp-server.zig | 57 +++++++++++++++++++++ zig-impl/other/testme.zig | 22 ++++++++ zig-impl/other/write-tcpd-pong-messages.zig | 31 +++++++++++ 9 files changed, 303 insertions(+) create mode 100644 zig-impl/other/double-close.zig create mode 100644 zig-impl/other/example-hexdump.zig create mode 100644 zig-impl/other/rcv-fd.zig create mode 100644 zig-impl/other/snd-fd.zig create mode 100644 zig-impl/other/test-fn.zig create mode 100644 zig-impl/other/test-tcp-client.zig create mode 100644 zig-impl/other/test-tcp-server.zig create mode 100644 zig-impl/other/testme.zig create mode 100644 zig-impl/other/write-tcpd-pong-messages.zig diff --git a/zig-impl/other/double-close.zig b/zig-impl/other/double-close.zig new file mode 100644 index 0000000..47180e2 --- /dev/null +++ b/zig-impl/other/double-close.zig @@ -0,0 +1,11 @@ +const std = @import("std"); +const print = std.debug.print; + +pub fn main() !u8 { + print("First close!\n", .{}); + std.os.close(1); + print("SECOND close!\n", .{}); + std.os.close(1); + print("Will it be printed?\n", .{}); + return 0; +} diff --git a/zig-impl/other/example-hexdump.zig b/zig-impl/other/example-hexdump.zig new file mode 100644 index 0000000..ea3a6a1 --- /dev/null +++ b/zig-impl/other/example-hexdump.zig @@ -0,0 +1,8 @@ +const msg_type = @intToEnum(Message.Type, try reader.readByte()); +try writer.writeByte(@enumToInt(self.t)); + +var hexbuf: [4000]u8 = undefined; +var hexfbs = std.io.fixedBufferStream(&hexbuf); +var hexwriter = hexfbs.writer(); +try hexdump.hexdump(hexwriter, "Message.read input buffer", buffer); +print("{s}\n", .{hexfbs.getWritten()}); diff --git a/zig-impl/other/rcv-fd.zig b/zig-impl/other/rcv-fd.zig new file mode 100644 index 0000000..6a91269 --- /dev/null +++ b/zig-impl/other/rcv-fd.zig @@ -0,0 +1,57 @@ +const std = @import("std"); +const net = std.net; +const print = std.debug.print; + +const receive_fd = @import("./exchange-fd.zig").receive_fd; + +fn disconnect(stream: *net.StreamServer) void { stream.close(); } + +fn server_init() net.StreamServer { + // no reuse_address and default kernel_backlog + return net.StreamServer.init(.{}); +} + +fn waiting_for_connection(stream: *net.StreamServer + , path: []const u8) !net.StreamServer.Connection { + var address = try net.Address.initUnix(path); + try stream.listen(address); + return stream.accept(); +} + +fn remove_unix_socket(path: []const u8) void { + std.fs.deleteFileAbsolute(path) catch |err| switch(err) { + else => { print("error: {}\n", .{err}); } + }; +} + +fn add_line_from_fd(fd: i32) !void { + _ = try std.os.write(fd, "SECOND LINE\n"); + std.os.close(fd); +} + +pub fn main() !u8 { + var path = "/tmp/TEST_EXCHANGE_FD"; + + print("Init UNIX server to {s}...\n", .{path}); + var stream = server_init(); + defer stream.deinit(); + + print("Waiting for a connection...\n", .{}); + var connection = try waiting_for_connection(&stream, path); + defer remove_unix_socket(path); + + print("Someone is connected! Receiving a file descriptor...\n", .{}); + var msgbuffer: [1500]u8 = undefined; + var msgsize: usize = 0; + var fd = try receive_fd(connection.stream.handle, msgbuffer[0..], &msgsize); + print("received fd: {}, payload: {s}\n", .{fd, msgbuffer[0..msgsize - 1]}); + + print("FD received, writing a line into the file...\n", .{}); + try add_line_from_fd(fd); + + print("Disconnection...\n", .{}); + disconnect(&stream); + + print("Disconnected!\n", .{}); + return 0; +} diff --git a/zig-impl/other/snd-fd.zig b/zig-impl/other/snd-fd.zig new file mode 100644 index 0000000..5365194 --- /dev/null +++ b/zig-impl/other/snd-fd.zig @@ -0,0 +1,43 @@ +const std = @import("std"); +const net = std.net; + +const send_fd = @import("./exchange-fd.zig").send_fd; + +const print = std.debug.print; + +fn disconnect(stream: net.Stream) void { stream.close(); } + +fn connect(path: []const u8) !net.Stream { + return try net.connectUnixSocket(path); +} + +fn add_line_in_file() !void { + var cwd = std.fs.cwd(); + var f = try cwd.createFile("some-file.log", .{.read = true}); + defer f.close(); + + var writer = f.writer(); + try writer.print("hello\n", .{}); +} + +pub fn main() !u8 { + var path = "/tmp/TEST_EXCHANGE_FD"; + + print("Connection to {s}...\n", .{path}); + var stream = try connect(path); + + print("Connected! Opening a file...\n", .{}); + var file = try std.fs.cwd().createFile("some-file.log", .{.read = true}); + defer file.close(); + + print("File opened! Writing some data into it...\n", .{}); + var writer = file.writer(); + try writer.print("hello this is the first process\n", .{}); + + print("Data written! Sending its fd...\n", .{}); + send_fd(stream.handle, "hello this is the payload", file.handle); + print("Sent fd! Disconnection...\n", .{}); + disconnect(stream); + print("Disconnected!\n", .{}); + return 0; +} diff --git a/zig-impl/other/test-fn.zig b/zig-impl/other/test-fn.zig new file mode 100644 index 0000000..882be4c --- /dev/null +++ b/zig-impl/other/test-fn.zig @@ -0,0 +1,25 @@ +const std = @import("std"); +const hexdump = @import("./hexdump.zig"); +const net = std.net; +const fmt = std.fmt; +const os = std.os; + +const print = std.debug.print; + +fn say_hello(some_number: i32) void { + print ("hello number {}\n", .{some_number}); +} + +fn say_coucou(some_number: i32) void { + print ("coucou number {}\n", .{some_number}); +} + +pub fn main() !u8 { + var fp: *const fn (i32) void = say_hello; + // print ("currently fp {any}\n", .{fp}); + fp(10); + fp = say_coucou; + // print ("currently fp {p}\n", .{fp.?}); + fp(20); + return 0; +} diff --git a/zig-impl/other/test-tcp-client.zig b/zig-impl/other/test-tcp-client.zig new file mode 100644 index 0000000..d51b1e8 --- /dev/null +++ b/zig-impl/other/test-tcp-client.zig @@ -0,0 +1,49 @@ +const std = @import("std"); +const net = std.net; +const fmt = std.fmt; +const os = std.os; + +const print = std.debug.print; +const testing = std.testing; +const print_eq = @import("./util.zig").print_eq; +const URI = @import("./util.zig").URI; + +fn connect_tcp(allocator: std.mem.Allocator) !net.Stream { + var buffer: [1000]u8 = undefined; + var fbs = std.io.fixedBufferStream(&buffer); + var writer = fbs.writer(); + + var address = std.process.getEnvVarOwned(allocator, "ADDRESS") catch |err| switch(err) { + error.EnvironmentVariableNotFound => blk: { + print("no ADDRESS envvar: connecting on 127.0.0.1:9000\n", .{}); + break :blk try allocator.dupe(u8, "127.0.0.1:9000"); + }, + else => { return err; }, + }; + defer allocator.free(address); + + try writer.print("{s}", .{address}); + var tcp_address = fbs.getWritten(); + + var iterator = std.mem.split(u8, tcp_address, ":"); + var real_tcp_address = iterator.first(); + var real_tcp_port = try std.fmt.parseUnsigned(u16, iterator.rest(), 10); + + print ("TCP address [{s}] port [{}]\n", .{real_tcp_address, real_tcp_port}); + + var socket_addr = try net.Address.parseIp(real_tcp_address, real_tcp_port); + var stream = try net.tcpConnectToAddress(socket_addr); + + return stream; +} + +pub fn main() !u8 { + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + var stream = try connect_tcp(allocator); + _ = try stream.write("coucou"); + stream.close(); + return 0; +} diff --git a/zig-impl/other/test-tcp-server.zig b/zig-impl/other/test-tcp-server.zig new file mode 100644 index 0000000..bd1ba85 --- /dev/null +++ b/zig-impl/other/test-tcp-server.zig @@ -0,0 +1,57 @@ +const std = @import("std"); +const net = std.net; +const fmt = std.fmt; +const os = std.os; + +const print = std.debug.print; +const testing = std.testing; +const print_eq = @import("./util.zig").print_eq; +const URI = @import("./util.zig").URI; + +fn init_tcp_server(allocator: std.mem.Allocator) !net.StreamServer { + var buffer: [1000]u8 = undefined; + var fbs = std.io.fixedBufferStream(&buffer); + var writer = fbs.writer(); + + var address = std.process.getEnvVarOwned(allocator, "ADDRESS") catch |err| switch(err) { + error.EnvironmentVariableNotFound => blk: { + print("no ADDRESS envvar: TCPd will listen on 127.0.0.1:9000\n", .{}); + break :blk try allocator.dupe(u8, "127.0.0.1:9000"); + }, + else => { return err; }, + }; + defer allocator.free(address); + + try writer.print("{s}", .{address}); + var tcp_address = fbs.getWritten(); + + var iterator = std.mem.split(u8, tcp_address, ":"); + var real_tcp_address = iterator.first(); + var real_tcp_port = try std.fmt.parseUnsigned(u16, iterator.rest(), 10); + + print ("TCP address [{s}] port [{}]\n", .{real_tcp_address, real_tcp_port}); + + var server = net.StreamServer.init(.{.reuse_address = true}); + var socket_addr = try net.Address.parseIp(real_tcp_address, real_tcp_port); + try server.listen(socket_addr); + + return server; +} + +fn accept_read(server: *net.StreamServer) !void { + var client = try server.accept(); // net.StreamServer.Connection + var buffer: [1000]u8 = undefined; + var size = try client.stream.read(&buffer); + print ("received: {s}\n", .{buffer[0..size]}); + client.stream.close(); +} + +pub fn main() !u8 { + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + var streamserver = try init_tcp_server(allocator); + try accept_read(&streamserver); + return 0; +} diff --git a/zig-impl/other/testme.zig b/zig-impl/other/testme.zig new file mode 100644 index 0000000..10ad421 --- /dev/null +++ b/zig-impl/other/testme.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const hexdump = @import("./hexdump.zig"); +const net = std.net; +const fmt = std.fmt; +const os = std.os; + +const print = std.debug.print; +const ipc = @import("./main.zig"); +const Message = ipc.Message; + +pub fn main() !u8 { + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var ctx = try ipc.Context.init(allocator); + ctx.deinit(); // There. Can't leak. Isn't Zig wonderful? + + print("Goodbye\n", .{}); + return 0; +} diff --git a/zig-impl/other/write-tcpd-pong-messages.zig b/zig-impl/other/write-tcpd-pong-messages.zig new file mode 100644 index 0000000..af7de93 --- /dev/null +++ b/zig-impl/other/write-tcpd-pong-messages.zig @@ -0,0 +1,31 @@ +const std = @import("std"); +const ipc = @import("./ipc.zig"); +const hexdump = @import("./hexdump.zig"); +const print = std.debug.print; + + +pub fn main() !void { + var allocator = std.heap.c_allocator; + + var buffer = [_]u8{0} ** 10000; + var fbs = std.io.fixedBufferStream(&buffer); + var writer = fbs.writer(); + + var m = try ipc.Message.init (9, allocator, "hello this is me!"); + defer m.deinit(); + + _ = try m.write(writer); + + var msg_bytes = fbs.getWritten(); + + // var hexbuf: [4000]u8 = undefined; + // var hexfbs = std.io.fixedBufferStream(&hexbuf); + // var hexwriter = hexfbs.writer(); + // try hexdump.hexdump(hexwriter, "What should be written in output", msg_bytes); + // print("{s}\n", .{hexfbs.getWritten()}); + + var out = std.io.getStdOut(); + _ = try out.write("pong"); + std.time.sleep(1_000_000_000); // wait for 1 seconds + _ = try out.write(msg_bytes); +}