[erlang-questions] How do you kill an OS process that was opened with open_port on a brutal_kill?

Vans S <>
Fri Nov 25 18:17:33 CET 2016


Per Hedeland and José Valim that method works great.  One small peeve is it makes an extra process but the only way around this would be to patch the OS Processes code to terminate when stdin closes.  For now using the shell script is more then enough.



On Friday, November 25, 2016 6:33 AM, Per Hedeland <> wrote:
On 2016-11-25 11:27, José Valim wrote:
> If I remember correctly, the stdin of the program started with open_port will be closed when the Erlang VM terminates.

Right - this is guaranteed by the OS kernel, which closes all open file
descriptors for a process when it terminates. Should be true even for
Windows with whatever is used to communicate with port programs there.

> So if the OS process is listening to stdin and exiting when the stdin closes, you
> don't need to worry about terminating it.

Yes. And this is the *only* way to ensure that the port program *always*
terminates when it should - it covers all of

- port is explicitly closed
- port-owning Erlang process terminates
- Erlang VM terminates

With Raimo's suggestion, the port program will continue to run if the
Erlang VM terminates "abruptly" (e.g. killed by e.g. the OOM-killer, or
failing to allocate memory). The design that stipulates that port
programs should (attempt to) read stdin and terminate when they see EOF
wasn't done on a whim...

> When they don't do so, you can also write a script that spawns the OS process and traverses stdin until it closes and then it terminates the OS process when stdin closes. Something like:
> 
>     #!/bin/bash
>     name=$1
>     shift
>     $name $*
>     pid=$!
>     while read line ; do
>       :
>     done < /dev/stdin
>     kill -KILL $pid
> 
> 
> If you save it as "wrap" then you can start your OS process as "wrap NAME ARGS". This can be handy if you cannot rely on C/C++ extensions. If anyone knows any drawback to such approach, I would love
> to hear.

Well, your script is missing a '&' on the "$name $*" line to make the
"target" program run in the (script's) background, but otherwise it
should be fine. I'd like to suggest a bit of simplification and
increased portability though:

   #!/bin/sh
   "$@" &
   pid=$!
   while read line ; do
     :
   done
   kill -KILL $pid

(And you could of course using something "nicer" than -KILL, e.g. -TERM,
if you are sure that it will be sufficient to terminate the program.)

--Per Hedeland

_______________________________________________
erlang-questions mailing list

http://erlang.org/mailman/listinfo/erlang-questions


More information about the erlang-questions mailing list