[erlang-questions] managing OS processes

Tim Watson <>
Tue May 29 14:38:56 CEST 2012


Guys,

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.

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. 

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). 

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! 

Cheers,
Tim

On 29 May 2012, at 12:13, Robert Raschke wrote:

> 
> On Tue, May 29, 2012 at 10:21 AM, Ciprian Dorin Craciun <> wrote:
>    Hello all!
> 
>    I don't think its the right way (although it seems to be suggested
> by the Erlang manual or somewhere else I've read it), but the way I
> did it was to write a small C program that is the one "babysitting"
> the real process, and a small Erlang wrapper.
> 
>    The code is here (Apache 2.0 licensed):
>      https://github.com/cipriancraciun/mosaic-node/tree/development/applications/mosaic-harness/sources
>      https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness_backend.erl
>      https://github.com/cipriancraciun/mosaic-node/blob/development/applications/mosaic-harness/sources/mosaic_harness.c
> 
>    The C program allows the following:
>    * it uses a small protocol based on JSON to communicate with the
> Erlang wrapper, using solely `stdin` / `stdout` between itself and
> Erlang, and between itself and the "babysitted" program;
>    * it allows a single process to be executed at a time (controlling
> environment, arguments, and working directory); (it could be extended
> to multiple process in parallel if wanted;) (but you can run it again
> if you want;)
>    * it allows a signal to be sent;
>    * it allows "exchange" messages to be sent to and from Erlang and
> the process;
>    * it allows brutal termination; (i.e. SIGKILL;)
>    * if `stdin` is closed by the Erlang side it kills the process;
>    * if `stdin` is closed by the process side it informs the Erlang side;
> 
>    The C part is a self-contained `.c` file (of about 2k lines, of
> which 25% are structure definitions), written in an event driven
> manner (no threads), statically linkable, depending only on the
> `jansson` library (for JSON), using mostly POSIX syscalls.
> 
>    I've successfully used it for about a year now (in non-production
> systems) and it behaves nicely.
> 
>    If someone finds it useful I could try to extract it in a
> standalone project.
> 
>    Ciprian.
> 
> 
> 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?
> 
> The approach is:
> 
> 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.
> 
> Thus you now have your command running in the backgroud, able to communicate using stdio with the Erlang process that started the proxy.
> 
> If you want to stop the command, you invoke the proxy with the process id you got earlier and it kills it using TerminateProcess().
> 
> Robby
> 
> 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.
> 
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120529/4a2c24cd/attachment.html>


More information about the erlang-questions mailing list