I am using Erlang port to read output of Linux process. I'd like the Linux process to be automatically killed whenever my connected Erlang process dies. From the docs, it seems to me that this should automatically happen, but it does not.
Minimal example. Put this in the file test.erl:
-module(test).
-export([start/0, spawn/0]).
start() ->
Pid = spawn_link(?MODULE, spawn, []),
register(test, Pid).
spawn() ->
Port = open_port({spawn, "watch date"},[stream, exit_status]),
loop([{port, Port}]).
loop(State) ->
receive
die ->
error("died");
Any ->
io:fwrite("Received: ~p~n", [Any]),
loop(State)
end.
Then, in erl shell:
1> c(test).
{ok,test}
2> test:start().
true
The process starts and prints some data received from the Linux "watch" command every 2 seconds.
Then, I make the Erlang process crash:
3> test ! die.
=ERROR REPORT==== 26-May-2021::13:24:01.057065 ===
Error in process <0.95.0> with exit value:
{"died",[{test,loop,1,[{file,"test.erl"},{line,15}]}]}
** exception exit: "died"
in function test:loop/1 (test.erl, line 15)
The Erlang process dies as expected, the data from "watch" stops appearing but the watch process still keeps running in the background as can be seen in Linux (not erl) terminal:
fuxoft@frantisek:~$ pidof watch
1880127
In my real-life scenario, I am not using "watch" command but other process that outputs data and accepts no input. How can I make it automaticall die when my connected Erlang process crashes? I can do this using Erlang supervisor and manually issuing the "kill" command when Erlang process crashes but I thought this could be done easier and cleaner.