Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Killing a process connected to an erlang's port

Tags:

erlang

I want to write a some kind of supervisor and I'm trying to implement function that closes an external program. The external process is connected to an erlang's code with a port. I have no idea how to close this program, by sending a signal or anything else. Closing a port is not a solution, becouse I've checked that many programs doesn't exit on SIGPIPE. Have you got any ideas how to do it?

like image 659
Wojciech Reszelewski Avatar asked Dec 17 '12 07:12

Wojciech Reszelewski


People also ask

How do I kill a process in Erlang?

A process can terminate itself by calling one of the BIFs exit(Reason), erlang:error(Reason), erlang:error(Reason, Args), erlang:fault(Reason) or erlang:fault(Reason, Args). The process then terminates with reason Reason for exit/1 or {Reason,Stack} for the others.

What is Erlang processes?

Erlang processes are light-weight (grow and shrink dynamically) with small memory footprint, fast to create and terminate and the scheduling overhead is low.

What is PID in Erlang?

Each process in erlang has a process identifier ( Pid ) in this format <x.x.x> , x being a natural number. Below is an example of a Pid <0.1252.0> Pid can be used to send messages to the process using 'bang' ( ! ), also Pid can be bounded to a variable, both are shown below. MyProcessId = self().

What does spawn do in Erlang?

spawn() creates a new process and returns the pid. The new process starts executing in Module:Name(Arg1,...,ArgN) where the arguments are the elements of the (possible empty) Args argument list.


2 Answers

You can kill external process if you kill linked erlang process. Use this way:

-module(portest).
-export([start/1, init/1, kill/0]).

start(ExtPrg) ->
   spawn(?MODULE, init, [ExtPrg]).

init(ExtPrg) ->
   process_flag(trap_exit, true),
   Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
   register(extport, self()),
   loop(Port).

kill() ->
   exit(whereis(extport), kill).

But you cannot kill external process which blocked with IO read.

like image 44
17 revs, 13 users 59% Avatar answered Nov 08 '22 07:11

17 revs, 13 users 59%


You can use

{os_pid, OsPid} = erlang:port_info(Port, os_pid). 

to get the pid of the process in the OS (see http://erlang.org/doc/man/erlang.html#port_info-1 - I think you may need a recent version of Erlang for this to be included, I think the one installed by apt-get on Ubuntu 12.04 isn't recent enough, I know R15B02 has it though) and then

os:cmd(io_lib:format("kill -9 ~p", [OsPid])).

to kill it (http://erlang.org/doc/man/os.html#cmd-1).

like image 141
Tom H. Avatar answered Nov 08 '22 07:11

Tom H.