Boost logo

Boost Users :

Subject: [Boost-users] Issues with boost::process from the sandbox and the boost::process::child semantics
From: Jan Kundrát (jkt_at_[hidden])
Date: 2011-03-27 17:01:11


Hi folks,
this is my first post to this list, so I hope I'll include enough
information to make it useful. I'd like to write a class with the
following interface:

class Process {
public:
        Process(const std::vector<std::string> &args);
        std::string readEverythingReceivedSoFar();
        void write(const std::string &data);
private:
        something childProcess;
};

and when looking for building blocks to use, I came across the process
library in boost's sandbox [1]. On a first sight, it looks great and
implements much more than what I need now, and has a nice documentation
-- so far so good. But when I actually tried to use it, I wasn't able to
get it working without resorting to something which is an ugly hack to me.

It's obvious that I have to have some access to "the child process" from
the reading/writing methods, and -- because I don't like leaving zombie
processes behind me -- also from my destructor to be able to kill it. In
this library, there's a boost::process::child which is intended to be
used for exactly this purpose, so I tried to add that as that
"something" member.

For technical reasons (got to do some postprocessing to the
user-supplied arguments before I actually launch my process), I can't
initialize the childProcess in the initializer list before the actual
constructor body, which means that the compiler will have to initialize
it to something for me. It turns out that the boost::process::child
class is missing a default constructor, so my member can't be of that
type (unless I wanted to create a very artificial instance with a faked
PID, fabricated FDs etc).

So I had to use pointers for that, which is IMHO bad because it needs
dynamic memory allocation without a real reason. I realize that we're
talking about a fork() here, so a dynamic memory allocation is not a
problem from the performance point of view, but I prefer not to use it
unless I have to.

The only solution I could come up is the following:

private:
    std::tr1::shared_ptr<boost::process::child> childProcess;

and in the constructor:

childProcess.reset(new boost::process::child(boost::process::launch(exe,
arguments, ctx)));

...because I get a boost::process::child by value, so I have to invoke a
copy constructor and put that object on the heap, if I understand this
issue correctly. That smells fishy.

So, I'd highly appreciate if you could tell me whether my understanding
is correct, and if there's a better way out of here. In case I missed
something obvious, I'd be very happy to learn about that, too.

With kind regards,
Jan

[1] `svn co http://svn.boost.org/svn/boost/sandbox/process/`

-- 
Trojita, a fast e-mail client -- http://trojita.flaska.net/



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net