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.
|
[LibIPC][libipc] C examples: `pong` and `pongd` (simple service and its client, just echoing received messages).
|
||||||
Implementation is straightforward.
|
Implementations are straightforward.
|
||||||
|
|
||||||
# Build
|
## Build
|
||||||
|
|
||||||
`make`
|
`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].
|
Crystal LibIPC examples, using [libipc bindings shard][bindings].
|
||||||
|
|
||||||
## Installation
|
## Build
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Compiles all examples.
|
# Compiles all examples.
|
||||||
shards build
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
Currently there are 2 examples:
|
Currently there are 2 examples:
|
||||||
|
|
@ -21,7 +19,7 @@ Currently there are 2 examples:
|
||||||
./bin/pong # run the client
|
./bin/pong # run the client
|
||||||
```
|
```
|
||||||
|
|
||||||
# LICENCE
|
## LICENSE
|
||||||
|
|
||||||
ISC
|
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:
|
pongd:
|
||||||
main: src/pongd.cr
|
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:
|
dependencies:
|
||||||
ipc:
|
ipc:
|
||||||
git: https://git.baguette.netlib.re/Baguette/ipc.cr
|
git: https://git.baguette.netlib.re/Baguette/ipc.cr
|
||||||
branch: master
|
branch: master
|
||||||
|
|
||||||
crystal: 1.7.1
|
crystal: 1.8.2
|
||||||
|
|
||||||
license: ISC
|
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
|
ifdef STATIC
|
||||||
STATIC_BUILD ?= -static
|
STATIC_BUILD ?= -static
|
||||||
|
CRYSTAL_STATIC_BUILD ?= --static
|
||||||
|
ZIG_STATIC_BUILD ?= -Dstatic=true
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# For interactive completion in the shell.
|
# 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,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
link_and_install(pongd_exe);
|
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
|
all: build
|
||||||
|
|
||||||
|
include ../mk/makefile.utils
|
||||||
|
|
||||||
update-libipc:
|
update-libipc:
|
||||||
git submodule update
|
git submodule update
|
||||||
|
|
||||||
ZIG_OPTS ?=
|
ZIG_OPTS ?=
|
||||||
ZIG_OPTIM ?= ReleaseSafe
|
ZIG_OPTIM ?= ReleaseSafe
|
||||||
build:
|
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