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

Per Hedeland per@REDACTED
Fri Nov 25 12:33:09 CET 2016


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



More information about the erlang-questions mailing list