
As there has been a lot of feedback I started to update the library. There is now a new version available at <http://www.highscore.de/boost/gsoc2010/process.zip> (and of course in Subversion at <http://svn.boost.org/svn/boost/sandbox/SOC/2010/process/>). What has been changed? * The context class now uses delegates based on boost::function to configure standard streams. There is no class hierarchy anymore for stream behavior classes. Nothing needs to be created on the heap either (and consequently boost::shared_ptr is gone). Context objects can be reused now to create multiple child processes. * The delegates in the context class expect this signature: std::pair<handle, handle> (bool). There is a parameter of type bool passed to indicate whether an input or an output stream is configured. Now it's not required anymore to pass a parameter like input_stream or output_stream yourself. * All stream behaviors have been defined as function objects. While it would be possible to create standalone functions for some stream behaviors (like behavior::close which would return a pair of empty handles) for consistency I defined function objects only. * behavior::named_pipe now requires the developer to set the name of the pipe (and does not automatically generate a unique name anymore). * behavior::async_pipe is a new stream behavior which uses the minimum required pipe type on a platform to support asynchronous I/O. It's a typedef for (anonmyous) pipe on POSIX and a function object based on behavior::named_pipe on Windows (automatically generating a unique name with UuidCreateSequential()). I'd appreciate if you could comment on the changes. Especially have a look at: * this signature: std::pair<handle, handle> (bool). Shall we use std::pair<handle, handle> to return two handles for the child and parent process or a struct with member variables called parent_end and child_end? Shall we use a bool to indicate whether an input or output stream is configured or something else like an enumeration? I think it all depends on how many developers want to define new stream behaviors and if it's worth to make the signature a bit more self-explanatory? * the implementation of async_pipe on Windows. Are return values of Windows functions checked correctly? Is the return value of UuidCreateSequential() and UuidToStringA() the error code or must GetLastError() be called? Is it OK if we require developers to link against rpcrt4.lib on Windows because async_pipe uses UuidCreateSequential() now? * the example at <http://svn.boost.org/svn/boost/sandbox/SOC/2010/process/libs/process/example/redirect_to.cpp>. It uses a user-defined behavior class to redirect the child's standard error stream to the standard output stream. As the behavior of the standard error stream must somehow access the handle of the standard output stream I create the pipe myself before I set the stream behaviors. As the pipe must be used for the standard output stream though I define a forward function which I can bind to the respective delegate. Anyway, please have a look at the example and think about whether it makes sense or if there is anything to simplify. :-) What still has to be done? * The context class still has a default constructor only which initializes the stream behaviors to inherit standard streams. This is a problem for Windows GUI applications as they don't have standard streams (or at least they are closed). While the Named Constructor Idiom has been proposed what exactly should the done? Should the default constructor be private and developers must explicitly use a factory function to create a context object? Shall the factory function initialize all standard streams with the same behavior? Shall we provide a factory function which expects three parameters to initialize the standard streams? What's convenient and flexible and not too confusing? * I didn't get rid yet of boost::filesystem::filesystem_error, boost::algorithm::ends_with and boost::algorithm::iends_with in operations.hpp. I read Ilya's posting and understand that he is worried about including too much. I checked Boost.Filesystem's header files and saw that filesystem/exception.hpp is empty and the exception classes have been moved to filesystem/path.hpp. I don't know the reason but wonder whether this shouldn't be changed then in Boost.Filesystem. If a Boost library can't include a header file from another Boost library because the header file is too big the header file should be split? Boost.StringAlgorithms is better in this regard (and I included only boost/algorithm/string/predicate.hpp and not everything from Boost.StringAlgorithms; of course this header file includes other header files from Boost.StringAlgorithms again...). Anyway, if anyone wants to reimplement find_executable_in_path() and executable_to_progname() (both in operations.hpp) I'm fine with it. I'm honestly not that motivated to reinvent the wheel and hope I can spend my time doing something more productive. * The documentation must be updated (which I'll do when everyone agrees that the changes make sense). Boris