require "ipc" # TODO: Write documentation for `IPCd` module IPCd VERSION = "0.1.0" def self.start ipcd = IPC.new() ipcd.service_init "hello" ipcd.timer 10_000 ipcd.loop do |event| begin case event.type when LibIPC::EventType::Timer puts "Timer." when LibIPC::EventType::Connection fd = ipcd.connect "pong" ipcd.add_switch event.newfd, fd input = -> fn_input( LibC::Int, LibC::Char*, LibC::UInt64T*) output = -> fn_output(LibC::Int, LibC::Char*, LibC::UInt64T ) ipcd.switch_callbacks event.newfd, input, output puts "New connection (#{event.newfd}) now automatically switched to 'pong' (#{fd})!" when LibIPC::EventType::Disconnection puts "Disconnection from #{event.fd}." when LibIPC::EventType::MessageTx puts "Message sent to #{event.fd}." when LibIPC::EventType::MessageRx puts "Message received from #{event.fd}." when LibIPC::EventType::SwitchRx puts "Switch message received from #{event.fd}." when LibIPC::EventType::SwitchTx puts "Switch message sent to #{event.fd}." when LibIPC::EventType::Error puts "And error occured on fd #{event.fd}." else puts "Unhandled IPC event: #{event.class}." if event.responds_to?(:fd) puts "closing #{event.fd}" ipcd.close event.fd end end rescue exception puts "exception: #{typeof(exception)} - #{exception.message}" end end end end def fn_input(fd : LibC::Int, buffer : LibC::Char*, buflen : LibC::UInt64T*) : LibC::Char puts "switch input: #{fd}" io = IO::FileDescriptor.new fd, close_on_finalize: false slice = Bytes.new buffer, buflen.value len = io.read slice buflen.value = len.to_u64 return 2_u8 if (len == 0) 0_u8 rescue e puts "fn_input exception! #{e}" 1_u8 end def fn_output(fd : LibC::Int, buffer : LibC::Char*, buflen : LibC::UInt64T) : LibC::Char puts "switch output: #{fd}" slice = Bytes.new buffer, buflen io = IO::FileDescriptor.new fd, close_on_finalize: false io.write slice io.flush 0_u8 rescue e puts "fn_output exception! #{e}" 1_u8 end IPCd.start