The library jumped to Zig v0.15.2 which implies a new build system. `build.zig` now compiles libipc as both static and dynamic libraries, and provides an entry point to use `libipc` as-is for Zig applications. Some examples have been added to help new users play with the library. Thanks to these fairly complete examples, two (very small) leaks related to sentinel values (in arrays containing paths) were fixed.
96 lines
3.6 KiB
Zig
96 lines
3.6 KiB
Zig
// Example of a `pong` client using the C bindings.
|
|
const std = @import("std");
|
|
|
|
// Only bindings are available.
|
|
const libipc = @cImport({
|
|
@cInclude("../../../libipc.h");
|
|
});
|
|
|
|
const SERVICE = "pong";
|
|
const SERVICE_LEN = 4;
|
|
const MAX_MSG_SIZE = 10000;
|
|
|
|
pub fn main() !u8 {
|
|
var ctx : *anyopaque = undefined;
|
|
var ret : c_int = 0;
|
|
var servicefd : c_int = undefined;
|
|
var buffer : [MAX_MSG_SIZE]u8 = undefined;
|
|
var size : usize = MAX_MSG_SIZE;
|
|
var event_type : u8 = undefined;
|
|
var index : usize = 0;
|
|
var originfd : c_int = undefined;
|
|
|
|
std.debug.print("Init context.\n", .{});
|
|
ret = libipc.ipc_context_init (@ptrCast(&ctx));
|
|
|
|
if (ret != 0) {
|
|
std.debug.print("Cannot init context.\n", .{});
|
|
return 1;
|
|
}
|
|
|
|
defer {
|
|
std.debug.print("Deinit context.\n", .{});
|
|
libipc.ipc_context_deinit (@ptrCast(&ctx));
|
|
}
|
|
|
|
std.debug.print ("Connect to a 'pong' service.\n", .{});
|
|
ret = libipc.ipc_connect_service (ctx, &servicefd, SERVICE, SERVICE_LEN);
|
|
|
|
if (ret != 0) {
|
|
std.debug.print("Cannot connect to a service.\n", .{});
|
|
return 1;
|
|
}
|
|
|
|
std.debug.print ("Let's schedule a message.\n", .{});
|
|
ret = libipc.ipc_schedule (ctx, servicefd, "hello, plz bounce me", 21);
|
|
|
|
if (ret != 0) {
|
|
std.debug.print("Cannot schedule a message.\n", .{});
|
|
return 1;
|
|
}
|
|
|
|
std.debug.print("Let's set the timer to one second.\n", .{});
|
|
libipc.ipc_context_timer (ctx, 1000);
|
|
|
|
var should_continue : bool = true;
|
|
// var event_count : u32 = 0;
|
|
|
|
std.debug.print("Let's loop over events.\n", .{});
|
|
while(should_continue) {
|
|
size = MAX_MSG_SIZE;
|
|
var newfd : c_int = undefined;
|
|
const pbuffer : [*c]u8 = &buffer;
|
|
ret = libipc.ipc_wait_event (ctx, &event_type, &index, &originfd, &newfd, pbuffer, &size);
|
|
if (ret != 0) {
|
|
std.debug.print("Error while waiting for an event.", .{});
|
|
return 1;
|
|
}
|
|
|
|
// event_count += 1;
|
|
// std.debug.print("EVENT n°{d} type {d}\t", .{ event_count, event_type });
|
|
|
|
switch (event_type) {
|
|
libipc.ERROR => { std.debug.print("Error.", .{}); return 1; },
|
|
libipc.EXTERNAL => { std.debug.print("External (shouldn't happen).", .{}); return 1; },
|
|
libipc.SWITCH_RX => { std.debug.print("Switch RX (shouldn't happen).", .{}); return 1; },
|
|
libipc.SWITCH_TX => { std.debug.print("Switch TX (shouldn't happen).", .{}); return 1; },
|
|
libipc.CONNECTION => { std.debug.print("Connection (shouldn't happen).", .{}); return 1; },
|
|
libipc.DISCONNECTION => { std.debug.print("Disconnection (shouldn't happen).", .{}); return 1; },
|
|
libipc.TIMER => { std.debug.print("TIMER.\n", .{}); },
|
|
libipc.MESSAGE_TX => { std.debug.print("A message has been sent.\n", .{}); },
|
|
libipc.MESSAGE_RX => {
|
|
if (size == 0) {
|
|
std.debug.print("No message returned.\n", .{});
|
|
return 1;
|
|
}
|
|
buffer[size] = 0;
|
|
std.debug.print("Response (size {d}): {s}.\n", .{ size, buffer[0..size] });
|
|
// We received the response, quitting.
|
|
should_continue = false;
|
|
},
|
|
else => { std.debug.print("Unknown IPC message type.\n", .{}); return 1; },
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|