<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Guys,</div><div><br></div><div>This stuff is really good. But fundamentally, we're still in the world where the limitations of open_port are what dominates. Dave Smith's sh modules/functions for both rebar and retest handle this kind of proxy approach just fine, simply by using `sh -C 'echo $$; exec ' ++ Cmd` and using port io. Admittedly it doesn't support signal handling as cleanly.</div><div><br></div><div>I hear (on twitter) that there are improvements to port communication coming in R16, and I dearly hope that native processes will be with us by then. At that time, these issues *might* just go away, although they might not. </div><div><br></div><div>The other problem I run into is, what about daemon/detached scripts, things launched using setsid/nohup and/or put straight into the background? And how is your proxy program going to exhibit characteristics any different in this situation, where you cannot 'spawn' a sub-process (or whatever the windows equivalent is). </div><div><br></div><div>Anyway, despite my reticence, I think your programs both sounds pretty useful - although I'm bemused that you'd use JSON serialization instead of simply using the ei interface - and I would also suggest that packaging them as separate libraries would be very useful to the community, giving others the benefit of utilising your work! </div><div><br></div><div>Cheers,</div><div>Tim</div><div><br></div><div><div>On 29 May 2012, at 12:13, Robert Raschke wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br><div class="gmail_quote">On Tue, May 29, 2012 at 10:21 AM, Ciprian Dorin Craciun <span dir="ltr"><<a href="mailto:ciprian.craciun@gmail.com" target="_blank">ciprian.craciun@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    Hello all!<br>
<br>
    I don't think its the right way (although it seems to be suggested<br>
by the Erlang manual or somewhere else I've read it), but the way I<br>
did it was to write a small C program that is the one "babysitting"<br>
the real process, and a small Erlang wrapper.<br>
<br>
    The code is here (Apache 2.0 licensed):<br>
      <a href="https://github.com/cipriancraciun/mosaic-node/tree/development/applications/mosaic-harness/sources" target="_blank">https://github.com/cipriancraciun/mosaic-node/tree/development/applications/mosaic-harness/sources</a><br>

      <a href="https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness_backend.erl" target="_blank">https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness_backend.erl</a><br>

      <a href="https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness.c" target="_blank">https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness.c</a><br>

<br>
    The C program allows the following:<br>
    * it uses a small protocol based on JSON to communicate with the<br>
Erlang wrapper, using solely `stdin` / `stdout` between itself and<br>
Erlang, and between itself and the "babysitted" program;<br>
    * it allows a single process to be executed at a time (controlling<br>
environment, arguments, and working directory); (it could be extended<br>
to multiple process in parallel if wanted;) (but you can run it again<br>
if you want;)<br>
    * it allows a signal to be sent;<br>
    * it allows "exchange" messages to be sent to and from Erlang and<br>
the process;<br>
    * it allows brutal termination; (i.e. SIGKILL;)<br>
    * if `stdin` is closed by the Erlang side it kills the process;<br>
    * if `stdin` is closed by the process side it informs the Erlang side;<br>
<br>
    The C part is a self-contained `.c` file (of about 2k lines, of<br>
which 25% are structure definitions), written in an event driven<br>
manner (no threads), statically linkable, depending only on the<br>
`jansson` library (for JSON), using mostly POSIX syscalls.<br>
<br>
    I've successfully used it for about a year now (in non-production<br>
systems) and it behaves nicely.<br>
<br>
    If someone finds it useful I could try to extract it in a<br>
standalone project.<br>
<span class="HOEnZb"><font color="#888888"><br>
    Ciprian.<br>
</font></span><div class="HOEnZb"><div class="h5"><br></div></div></blockquote><div><br>I have a similar "proxy" to run killable external programs on Windows. It's part of a larger project though, so I'd need to extract it. Would there be interest for me to do that?<br>
<br>The approach is:<br><br>Start the proxy program using open_port/2 and send it the command to run, the proxy then uses DuplicateHandle() and CreateProcessW() to kick off the command in a separate OS process but with stdin/stdout/stderr forwarded from the proxy to the new external command, prints the OS process id back to Erlang and waits for the external OS process to finish.<br>
<br>Thus you now have your command running in the backgroud, able to communicate using stdio with the Erlang process that started the proxy.<br><br>If you want to stop the command, you invoke the proxy with the process id you got earlier and it kills it using TerminateProcess().<br>
<br>Robby<br><br>PS I vaguely remember getting the idea of passing back a process id for later kill purposes from some open source app that uses a similar approach to running killable commands from Erlang. Not that I can remember which one at the mooment, sorry.<br>
<br></div></div>
_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br><a href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a><br></blockquote></div><br></body></html>