100 lines
3.7 KiB
Zig
100 lines
3.7 KiB
Zig
// Example of a `pong` service 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 ("Create the 'pong' service.\n", .{});
|
|
ret = libipc.ipc_service_init (ctx, &servicefd, SERVICE, SERVICE_LEN);
|
|
|
|
if (ret != 0) {
|
|
std.debug.print("Cannot create the service.\n", .{});
|
|
return 1;
|
|
}
|
|
|
|
std.debug.print ("Listening to the standard input (press enter to quit).\n", .{});
|
|
ret = libipc.ipc_add_external (ctx, 0);
|
|
|
|
if (ret != 0) {
|
|
std.debug.print ("Cannot listen to standard input.", .{});
|
|
return 1;
|
|
}
|
|
|
|
std.debug.print("Set the timer to two seconds.\n", .{});
|
|
libipc.ipc_context_timer (ctx, 2000);
|
|
|
|
var event_count : u32 = 0;
|
|
|
|
std.debug.print("Let's loop over events.\n", .{});
|
|
while(true) {
|
|
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;
|
|
|
|
switch (event_type) {
|
|
libipc.ERROR => { std.debug.print("Error.", .{}); return 1; },
|
|
libipc.EXTERNAL => { std.debug.print("Quitting.\n", .{}); return 0; },
|
|
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 (fd {d}).\n", .{newfd}); },
|
|
libipc.DISCONNECTION => { std.debug.print("Disconnection (fd {d}).\n", .{originfd}); },
|
|
libipc.TIMER => { std.debug.print("\rTIMER ({d}).\r", .{event_count}); },
|
|
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("Message from {d} (size {d}): {s}.\n", .{ originfd, size, buffer[0..size] });
|
|
|
|
std.debug.print ("Schedule a message for {d}.\n", .{originfd});
|
|
ret = libipc.ipc_schedule (ctx, originfd, pbuffer, size);
|
|
|
|
if (ret != 0) {
|
|
std.debug.print("Cannot schedule a message.\n", .{});
|
|
return 1;
|
|
}
|
|
},
|
|
else => { std.debug.print("Unknown IPC message type.\n", .{}); return 1; },
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|