Compare commits
10 commits
b1f19b30d2
...
4ba5aa93f3
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ba5aa93f3 | |||
| 556bdb58dd | |||
| 29ece121aa | |||
| d187d02de7 | |||
| 39fc84934d | |||
| 1435515898 | |||
| b567a25969 | |||
| 0585110df4 | |||
| bb6fc237e8 | |||
| 55a1a8cba8 |
14 changed files with 236 additions and 10 deletions
19
README.md
Normal file
19
README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
[LibIPC][libipc] examples in many languages:
|
||||
- C
|
||||
- Zig
|
||||
- Crystal
|
||||
|
||||
and soon even more!
|
||||
|
||||
# Build
|
||||
|
||||
Just type `make` in the right directory.
|
||||
|
||||
# Some makefile utilities
|
||||
|
||||
All examples' makefiles include `mk/makefile.utils`.
|
||||
Go have a look.
|
||||
You'll be able to ask for a static build, run an application with valgrind with many options, and so on.
|
||||
For example: `make STATIC=1 build` will compile your example as a static executable (in all languages).
|
||||
|
||||
[libipc]: https://git.baguette.netlib.re/Baguette/libipc
|
||||
2
c/.gitignore
vendored
Normal file
2
c/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pong
|
||||
pongd
|
||||
25
c/README.md
25
c/README.md
|
|
@ -1,6 +1,25 @@
|
|||
Some C examples, nothing fancy.
|
||||
Implementation is straightforward.
|
||||
[LibIPC][libipc] C examples: `pong` and `pongd` (simple service and its client, just echoing received messages).
|
||||
Implementations are straightforward.
|
||||
|
||||
# Build
|
||||
## Build
|
||||
|
||||
`make`
|
||||
|
||||
Some options are available, such as static builds.
|
||||
|
||||
```sh
|
||||
make STATIC=1 # Build static executables.
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
./zig-out/bin/pongd # run the service
|
||||
./zig-out/bin/pong # run the client
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
|
||||
ISC
|
||||
|
||||
[libipc]: https://git.baguette.netlib.re/Baguette/libipc
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
# LibIPC examples
|
||||
|
||||
Crystal LibIPC examples, using [libipc bindings shard][bindings].
|
||||
|
||||
## Installation
|
||||
## Build
|
||||
|
||||
```sh
|
||||
# Compiles all examples.
|
||||
shards build
|
||||
make
|
||||
```
|
||||
|
||||
Currently there are 2 examples:
|
||||
|
|
@ -21,7 +19,7 @@ Currently there are 2 examples:
|
|||
./bin/pong # run the client
|
||||
```
|
||||
|
||||
# LICENCE
|
||||
## LICENSE
|
||||
|
||||
ISC
|
||||
|
||||
|
|
|
|||
37
crystal/makefile
Normal file
37
crystal/makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# The following shows how to use a library that is not installed.
|
||||
# Usage example: make LIBPATH=/tmp/libipc/zig-out/lib/ build run
|
||||
|
||||
LIBPATH ?=
|
||||
LD_LIBRARY_PATH=LD_LIBRARY_PATH=$(LIBPATH)
|
||||
CRYSTAL_LIBRARY_PATH=CRYSTAL_LIBRARY_PATH=$(LIBPATH)
|
||||
CRYSTAL_BUILD_OPTIONS ?=
|
||||
CRYSTAL_BUILD_OPTIONS += $(CRYSTAL_STATIC_BUILD)
|
||||
|
||||
LIBIPC_RUNDIR ?= /tmp/libipc-run
|
||||
|
||||
all: run
|
||||
build: build-pongd build-pong build-input2ipc build-fromipc
|
||||
run: run-pongd
|
||||
|
||||
include ../mk/makefile.utils
|
||||
|
||||
build-pongd:
|
||||
$(CRYSTAL_LIBRARY_PATH) shards build pongd $(CRYSTAL_BUILD_OPTIONS)
|
||||
|
||||
run-pongd:
|
||||
rm $(LIBIPC_RUNDIR)/pong 2>/dev/null || true
|
||||
$(LD_LIBRARY_PATH) ./bin/pongd
|
||||
|
||||
build-pong:
|
||||
$(CRYSTAL_LIBRARY_PATH) shards build pong $(CRYSTAL_BUILD_OPTIONS)
|
||||
|
||||
run-pong:
|
||||
$(LD_LIBRARY_PATH) ./bin/pong
|
||||
|
||||
-include makefile.user
|
||||
|
||||
build-input2ipc:
|
||||
$(CRYSTAL_LIBRARY_PATH) shards build input2ipc $(CRYSTAL_BUILD_OPTIONS)
|
||||
|
||||
build-fromipc:
|
||||
$(CRYSTAL_LIBRARY_PATH) shards build fromipc $(CRYSTAL_BUILD_OPTIONS)
|
||||
30
crystal/makefile.user
Normal file
30
crystal/makefile.user
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
WS_PORT ?= 8080
|
||||
WS_SERVICE ?= 127.0.0.1:$(WS_PORT)
|
||||
|
||||
WS_TARGET_SERVICE ?= pong
|
||||
WS_TARGET ?= unix:/tmp/.libipc-run/$(WS_TARGET_SERVICE)
|
||||
init-websocket-tcpd:
|
||||
@# '-b' binary, '-E' quit on end-of-file, 'ws-l' websocket URI to listen
|
||||
@# each connection is redirected to last parameter
|
||||
websocat -b -E ws-l:$(WS_SERVICE) $(WS_TARGET)
|
||||
|
||||
init-websocket-client:
|
||||
@# websocat -b -E tcp-l:127.0.0.1:9000 ws://127.0.0.1:9999
|
||||
websocat -b -E ws://$(WS_SERVICE)
|
||||
|
||||
#
|
||||
# The following rules help for debugging stuff.
|
||||
# Changes can happen from time to time depending on what I'm working on.
|
||||
#
|
||||
|
||||
TCP_SERVICE ?= 127.0.0.1:9000
|
||||
init-websocket-ipc-unix:
|
||||
@#websocat -b -E ws-l:$(WS_SERVICE) tcp:$(TCP_SERVICE)
|
||||
@#websocat -b -E ws-l:$(WS_SERVICE) | ./bin/input2ipc | nc -U /tmp/.libipc-run/pong
|
||||
websocat -b -E -s 8080 | ./bin/input2ipc | nc -U /tmp/.libipc-run/pong
|
||||
|
||||
# 1. read TCP messages (nc),
|
||||
# 2. convert them into IPC messages (input2ipc),
|
||||
# 3. send them through websocket (websocat).
|
||||
init-tcpd-ipc-websocket:
|
||||
nc -k -l 9000 | ./bin/input2ipc | make init-websocket-client
|
||||
|
|
@ -13,11 +13,20 @@ targets:
|
|||
pongd:
|
||||
main: src/pongd.cr
|
||||
|
||||
# Those two examples show what it is required to serialize and deserialize
|
||||
# an IPC message, which only is to add (and remove) the message length in
|
||||
# the first 4 bytes of the message.
|
||||
# They can be used to handle messages from a simple shell script.
|
||||
fromipc:
|
||||
main: src/fromipc.cr
|
||||
input2ipc:
|
||||
main: src/input2ipc.cr
|
||||
|
||||
dependencies:
|
||||
ipc:
|
||||
git: https://git.baguette.netlib.re/Baguette/ipc.cr
|
||||
branch: master
|
||||
|
||||
crystal: 1.7.1
|
||||
crystal: 1.8.2
|
||||
|
||||
license: ISC
|
||||
|
|
|
|||
7
crystal/src/fromipc.cr
Normal file
7
crystal/src/fromipc.cr
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Read an IPC network packet and remove the first 4 bytes.
|
||||
buffer = Bytes.new 1_000_000
|
||||
while true
|
||||
len = STDIN.read buffer
|
||||
break if len == 0
|
||||
STDOUT.write buffer[4.. len -1]
|
||||
end
|
||||
8
crystal/src/input2ipc.cr
Normal file
8
crystal/src/input2ipc.cr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Input to IPC network packets.
|
||||
buffer = Bytes.new 1_000_000
|
||||
while true
|
||||
len = STDIN.read buffer
|
||||
break if len == 0
|
||||
STDOUT.write_bytes len, IO::ByteFormat::BigEndian
|
||||
STDOUT.write buffer[0.. len -1]
|
||||
end
|
||||
51
crystal/src/tcp-unix-to-ipc-unix.cr
Normal file
51
crystal/src/tcp-unix-to-ipc-unix.cr
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# WARNING: This code is for DEBUG only.
|
||||
|
||||
# Listen to a UNIX socket, connect to another one.
|
||||
require "ipc"
|
||||
|
||||
ipc = IPC.new
|
||||
ipc.timer 5000 # timer event every 5 seconds
|
||||
fd = ipc.connect "pong" # 'pong' service
|
||||
|
||||
ipc.loop do |event|
|
||||
case event.type
|
||||
when LibIPC::EventType::MessageRx
|
||||
m = event.message
|
||||
if m.nil?
|
||||
puts "No message"
|
||||
else
|
||||
received = String.new(m.to_unsafe, m.size)
|
||||
pp! received
|
||||
ipc.schedule event.fd, m, m.size
|
||||
end
|
||||
when LibIPC::EventType::MessageTx
|
||||
puts "A message has been sent"
|
||||
when LibIPC::EventType::Connection
|
||||
puts "A client just connected #JOY"
|
||||
when LibIPC::EventType::Disconnection
|
||||
puts "A client just disconnected #SAD"
|
||||
when LibIPC::EventType::Timer
|
||||
STDOUT.write "\rTimer!".to_slice
|
||||
when LibIPC::EventType::External
|
||||
else
|
||||
puts "Unexpected: #{event.type}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
# Read an IPC network packet and remove the first 4 bytes.
|
||||
buffer = Bytes.new 1_000_000
|
||||
while true
|
||||
len = STDIN.read buffer
|
||||
break if len == 0
|
||||
STDOUT.write buffer[4.. len -1]
|
||||
end
|
||||
|
||||
# Input to IPC network packets.
|
||||
buffer = Bytes.new 1_000_000
|
||||
while true
|
||||
len = STDIN.read buffer
|
||||
break if len == 0
|
||||
STDOUT.write_bytes len, IO::ByteFormat::BigEndian
|
||||
STDOUT.write buffer[0.. len -1]
|
||||
end
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
ifdef STATIC
|
||||
STATIC_BUILD ?= -static
|
||||
CRYSTAL_STATIC_BUILD ?= --static
|
||||
ZIG_STATIC_BUILD ?= -Dstatic=true
|
||||
endif
|
||||
|
||||
# For interactive completion in the shell.
|
||||
|
|
|
|||
34
zig/README.md
Normal file
34
zig/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
Zig [LibIPC][libipc] examples:
|
||||
`pong` and `pongd` (as you find in all other examples).
|
||||
`tcpd` and `ipcd`, to make any LibIPC application network-ready.
|
||||
Documentation will come soon for these.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
# Compiles all examples.
|
||||
make
|
||||
```
|
||||
|
||||
Several options are available.
|
||||
|
||||
```sh
|
||||
# Compiles all examples.
|
||||
make STATIC=1 # Build static executables.
|
||||
make ZIG_OPTIM=ReleaseSmall # Build small executables.
|
||||
```
|
||||
|
||||
Read the makefile.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
./zig-out/bin/pongd # run the service
|
||||
./zig-out/bin/pong # run the client
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
|
||||
ISC
|
||||
|
||||
[libipc]: https://git.baguette.netlib.re/Baguette/libipc
|
||||
|
|
@ -58,4 +58,12 @@ pub fn build(b: *std.Build) void {
|
|||
.optimize = optimize,
|
||||
});
|
||||
link_and_install(pongd_exe);
|
||||
|
||||
const is_static = b.option(bool, "static", "Compile static binaries.") orelse false;
|
||||
if (is_static) {
|
||||
ipcd_exe.linkage = .static;
|
||||
tcpd_exe.linkage = .static;
|
||||
pong_exe.linkage = .static;
|
||||
pongd_exe.linkage = .static;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
all: build
|
||||
|
||||
include ../mk/makefile.utils
|
||||
|
||||
update-libipc:
|
||||
git submodule update
|
||||
|
||||
ZIG_OPTS ?=
|
||||
ZIG_OPTIM ?= ReleaseSafe
|
||||
build:
|
||||
zig build -Doptimize=$(ZIG_OPTIM) $(ZIG_OPTS)
|
||||
zig build -Doptimize=$(ZIG_OPTIM) $(ZIG_OPTS) $(ZIG_STATIC_BUILD)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue