| Author |
Message |
|
| asergey |
Posted: Wed Oct 31, 2007 4:51 am |
|
|
|
User
Joined: 12 Mar 2005
Posts: 313
|
Hi,
I am having a problem shutting down a port program started using
open_port({spawn, Exe}, [binary, {packet, 2}, nouse_stdio, exit_status]).
When the owner Pid dies or explicitly calls port_close(Port) the linked
OS process remains running. It is a 3rd party binary interpreter. Is
it because it might be intercepting SIGINT or some other signals?
Is there a way to figure out it's OS pid and shut it down or is there a
"proper" way of killing it from within the emulator? (doing
os:cmd("pkill ExeName") is not an option as there might be many
instances of ExeName running. I looked through port_info/1 options but
don't see a way of determining port's OS pid.
Serge
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| asergey |
Posted: Wed Oct 31, 2007 12:08 pm |
|
|
|
User
Joined: 12 Mar 2005
Posts: 313
|
I reread this email and realized that I forgot to mention the fact that
in my understanding port_close/1 merely closes its end of the pipe used
to communicate with the port process. So in this case if the running
port program is in the middle of a blocking call it won't detect the
closing of the file descriptor it uses to communicate with Erlang and
will continue running. So if I wanted to kill that port by sending an
appropriate signal from Erlang how can I determine the OS pid of the port?
The obvious answer is to communicate that OS pid back to Erlang through
the pipe, but in this particular case it takes over two to three minutes
before the port loads all components and starts reading its end of the
pipe, and I'd like to be able to kill it prior to that.
Any suggestions?
Serge
Serge Aleynikov wrote:
> Hi,
>
> I am having a problem shutting down a port program started using
> open_port({spawn, Exe}, [binary, {packet, 2}, nouse_stdio, exit_status]).
>
> When the owner Pid dies or explicitly calls port_close(Port) the linked
> OS process remains running. It is a 3rd party binary interpreter. Is
> it because it might be intercepting SIGINT or some other signals?
>
> Is there a way to figure out it's OS pid and shut it down or is there a
> "proper" way of killing it from within the emulator? (doing
> os:cmd("pkill ExeName") is not an option as there might be many
> instances of ExeName running. I looked through port_info/1 options but
> don't see a way of determining port's OS pid.
>
> Serge
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Wed Oct 31, 2007 1:04 pm |
|
|
|
Guest
|
Serge Aleynikov <saleyn@gmail.com> wrote:
>
>I reread this email and realized that I forgot to mention the fact that
>in my understanding port_close/1 merely closes its end of the pipe used
>to communicate with the port process.
Correct - i.e. there are no signals sent.
> So in this case if the running
>port program is in the middle of a blocking call it won't detect the
>closing of the file descriptor it uses to communicate with Erlang and
>will continue running. So if I wanted to kill that port by sending an
>appropriate signal from Erlang how can I determine the OS pid of the port?
>
>The obvious answer is to communicate that OS pid back to Erlang through
>the pipe, but in this particular case it takes over two to three minutes
>before the port loads all components and starts reading its end of the
>pipe, and I'd like to be able to kill it prior to that.
Hm, but after it has done that loading, this "3rd party binary
interpreter" will actually start communicating with Erlang on fd 3/4,
using {packet, 2} format? I guess not, i.e. you probably have some
wrapper around it - and if so, can't you send the pid from the wrapper
code *before* doing all the loading?
Alternatively, you could experiment with something along the lines of
{spawn, Exe ++ " & echo $!"}
That obviously won't work as-is with {packet, 2}, so it has to be a bit
more complex, and the backgrounding *might* mess up the pipe plumbing,
but I don't really think it should.
--Per Hedeland
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| asergey |
Posted: Wed Oct 31, 2007 1:49 pm |
|
|
|
User
Joined: 12 Mar 2005
Posts: 313
|
Per Hedeland wrote:
> Hm, but after it has done that loading, this "3rd party binary
> interpreter" will actually start communicating with Erlang on fd 3/4,
> using {packet, 2} format?
Yes, if everything goes well in the initialization step.
> I guess not, i.e. you probably have some
> wrapper around it - and if so, can't you send the pid from the wrapper
> code *before* doing all the loading?
I don't have a wrapper - the interpreter does some heavy weight
initialization (loading a bunch (~ 200!!!) of shared objects) and at
some point will evaluate my script that would communicate with Erlang
through a pipe. If anything goes wrong I'd like to be able to kill the
beast by sending a fatal signal (and it would not be desirable to
introduce some light-weight middleman process that would sit between
Erlang and the interpreter and do all intermediate pipe marshaling).
> Alternatively, you could experiment with something along the lines of
>
> {spawn, Exe ++ " & echo $!"}
>
> That obviously won't work as-is with {packet, 2}, so it has to be a bit
> more complex, and the backgrounding *might* mess up the pipe plumbing,
> but I don't really think it should.
Thanks, I'll try, though I am doubtful that sending a process in the
background won't hurt the piping setup.
Serge
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Wed Oct 31, 2007 4:41 pm |
|
|
|
Guest
|
Serge Aleynikov <saleyn@gmail.com> wrote:
>
>Per Hedeland wrote:
>> I guess not, i.e. you probably have some
>> wrapper around it - and if so, can't you send the pid from the wrapper
>> code *before* doing all the loading?
>
>I don't have a wrapper - the interpreter does some heavy weight
>initialization (loading a bunch (~ 200!!!) of shared objects) and at
>some point will evaluate my script that would communicate with Erlang
>through a pipe.
Ah, OK.
>> Alternatively, you could experiment with something along the lines of
>>
>> {spawn, Exe ++ " & echo $!"}
>>
>> That obviously won't work as-is with {packet, 2}, so it has to be a bit
>> more complex, and the backgrounding *might* mess up the pipe plumbing,
>> but I don't really think it should.
>
>Thanks, I'll try, though I am doubtful that sending a process in the
>background won't hurt the piping setup.
Actually I'm pretty sure it would work, the backgrounded process should
just inherit the pipe file descriptors - and a quick test seems to
confirm it. But you definitely lose the exit_status as your interpreter
process is no longer a child of the VM process. So, here's a wrapper for
you, with "more complex" and all:
1> Exe = "sleep 1000".
"sleep 1000"
2> Wrapper = "echo $$ | awk '{printf \"%c%c%s\",0,length($1),$1}' >&4; exec ".
"echo $$ | awk '{printf \"%c%c%s\",0,length($1),$1}' >&4; exec "
3> Settings = [binary, {packet, 2}, nouse_stdio, exit_status].
[binary,{packet,2},nouse_stdio,exit_status]
4> Port = open_port({spawn, Wrapper ++ Exe}, Settings).
#Port<0.95>
5> Pid = receive {Port, {data, P}} -> binary_to_list(P) end.
"97122"
6> os:cmd("kill " ++ Pid).
[]
7> Status = receive {Port, {exit_status, S}} -> S end.
143
8>
--Per
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| asergey |
Posted: Thu Nov 01, 2007 4:25 am |
|
|
|
User
Joined: 12 Mar 2005
Posts: 313
|
Thanks Per, this is quite clever!
Serge
Per Hedeland wrote:
> 1> Exe = "sleep 1000".
> "sleep 1000"
> 2> Wrapper = "echo $$ | awk '{printf \"%c%c%s\",0,length($1),$1}' >&4; exec ".
> "echo $$ | awk '{printf \"%c%c%s\",0,length($1),$1}' >&4; exec "
> 3> Settings = [binary, {packet, 2}, nouse_stdio, exit_status].
> [binary,{packet,2},nouse_stdio,exit_status]
> 4> Port = open_port({spawn, Wrapper ++ Exe}, Settings).
> #Port<0.95>
> 5> Pid = receive {Port, {data, P}} -> binary_to_list(P) end.
> "97122"
> 6> os:cmd("kill " ++ Pid).
> []
> 7> Status = receive {Port, {exit_status, S}} -> S end.
> 143
> 8>
>
> --Per
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Thu Nov 01, 2007 7:09 am |
|
|
|
Guest
|
Serge Aleynikov <saleyn@gmail.com> wrote:
>
>Thanks Per, this is quite clever!
Though it's probably better to write the wrapper in C - some versions of
awk refuse to print NUL characters (e.g. the default one on Solaris -
/usr/xpg4/bin/awk a.k.a. nawk works there though, so it could be fixed
by setting $PATH) - or if you don't mind a dependency on perl, that
would be more "portable".
--Per
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|