Skip to content

Instantly share code, notes, and snippets.

@peerreynders
Created December 18, 2018 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peerreynders/c41186ede4f4b32103e41c58a807e860 to your computer and use it in GitHub Desktop.
Save peerreynders/c41186ede4f4b32103e41c58a807e860 to your computer and use it in GitHub Desktop.
Elixir port using named pipe via UNDOCUMENTED open_port/2 functionality
defmodule FromPipe do
#
# NOTE: this use of ports is based on UNDOCUMENTED functionality
# of the open_port/2 function - i.e. could stop working
# in any future release
# http://erlang.org/doc/man/erlang.html#open_port-2
#
# See also:
# Erlang and Named Pipes
# https://gist.github.com/jaredmorrow/1c342c6e9156eddd20b2
#
# Reading Named Pipes with Elixir
# https://blog.ironbay.co/reading-named-pipes-with-elixir-c5c614a32f25
#
# Rate limiting Ports
# https://elixirforum.com/t/rate-limiting-ports/9094
#
# Elixir port using named pipe with forwarding script
# https://gist.github.com/peerreynders/cbefdef71ce85fa0017d8d3262a9e1cd
#
# Elixir port using named pipe with releasing script
# https://gist.github.com/peerreynders/fb92fa4fe78d825ff82803f78f2fd551
#
@pipe_name "/tmp/testpipe"
@from_pipe_prep "./from_pipe_prep"
# delete previous named pipe and create a fresh, empty one
defp prep() do
path = Path.expand(@from_pipe_prep)
System.cmd(path, [@pipe_name])
end
defp start do
# IMPORTANT: pipe_name needs to be a charlist
@pipe_name
# to use "UNDOCUMENTED" Erlang functionality
|> to_charlist()
|> Port.open([:binary, {:line, 1024}, :eof])
end
defp stop(port) do
Port.close(port)
:ok
end
defp loop(port) do
receive do
{^port, {:data, {:eol, "quit"}}} ->
stop(port)
{^port, {:data, {:eol, data}}} ->
IO.puts("eol data: #{data}")
loop(port)
{^port, {:data, {:noeol, data}}} ->
IO.puts("noeol data: #{data}")
loop(port)
msg ->
IO.puts("other: #{inspect(msg)}")
loop(port)
end
end
def run() do
prep()
loop(start())
end
end
#!/bin/bash
# file: from_pipe_prep pipe_name
if [[ -p $1 ]]; then
rm -f $1
fi
mkfifo $1
1$ iex
Erlang/OTP 21 [erts-10.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c("from_pipe.ex")
[FromPipe]
iex(2)> FromPipe.run()   
eol data: hello
eol data: world
noeol data: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEF
eol data: GHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
:ok
iex(3)> 
2$ echo hello >/tmp/testpipe
2$ echo world >/tmp/testpipe
2$ echo 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ >/tmp/testpipe
2$ echo quit >/tmp/testpipe
2$ 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment