Only in ./process: basic_pipeline.hpp diff -ru ./process/child.hpp /home/cfairles/src/skotty/boost/process/child.hpp --- ./process/child.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/child.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -1,36 +1,11 @@ // // Boost.Process // -// Copyright (c) 2006 Julio M. Merino Vidal. +// Copyright (c) 2006, 2007 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -44,7 +19,7 @@ #define BOOST_PROCESS_CHILD_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) extern "C" { @@ -52,7 +27,7 @@ # include } # include -# include +# include "boost/process/exceptions.hpp" # include #elif defined(BOOST_PROCESS_WIN32_API) # include @@ -61,20 +36,21 @@ #endif #include +#include #include -#include -#include -#include -#include +#include "boost/process/detail/pipe.hpp" +#include "boost/process/pistream.hpp" +#include "boost/process/postream.hpp" +#include "boost/process/process.hpp" +#include "boost/process/status.hpp" #include namespace boost { namespace process { -namespace detail { -struct factories; -} +template< class Executable, class Arguments > class basic_pipeline; +class launcher; // ------------------------------------------------------------------------ @@ -84,34 +60,9 @@ //! The child class implements the Child concept in an operating system //! agnostic way. //! -class child +class child : public process { public: -#if defined(BOOST_PROCESS_DOXYGEN) - //! - //! \brief Opaque name for the native process' handle type. - //! - //! Each operating system identifies processes using a specific type. - //! The \a handle_type type is used to transparently refer to a process - //! regarless of the operating system in which this class is used. - //! - //! If this class is used in a POSIX system, \a NativeSystemHandle is - //! an integer type while it is a \a HANDLE in a Win32 system. - //! - typedef NativeSystemHandle handle_type; -#elif defined(BOOST_PROCESS_WIN32_API) - typedef HANDLE handle_type; -#elif defined(BOOST_PROCESS_POSIX_API) - typedef pid_t handle_type; -#endif - - //! - //! \brief Returns the system handle that identifies the process. - //! - //! Returns the system handle that identifies the process. - //! - handle_type get_handle(void) const; - //! //! \brief Gets a reference to the child's standard input stream. //! @@ -146,15 +97,10 @@ //! \remark Blocking remarks: This call blocks if the child //! process has not finalized execution and waits until it terminates. //! - status wait(void); + const status wait(void); private: //! - //! \brief The handle that identifies the process. - //! - handle_type m_handle; - - //! //! \brief The standard input stream attached to the child process. //! //! This postream object holds the communication channel with the @@ -184,7 +130,7 @@ //! boost::shared_ptr< pistream > m_sstderr; -protected: +public: // XXX? //! //! \brief Constructs a new child object representing a just spawned //! child process. @@ -202,21 +148,32 @@ //! business in creating representations of live processes himself; //! the library takes care of that in all cases. //! - child(handle_type h, + child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr); - friend struct detail::factories; + template< class Executable, class Arguments > friend class basic_pipeline; + friend class launcher; }; // ------------------------------------------------------------------------ +//! +//! \brief Collection of child objects. +//! +//! This convenience type represents a collection of child objects backed +//! by a vector. +//! +typedef std::vector< child > children; + +// ------------------------------------------------------------------------ + inline -child::child(handle_type h, +child::child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr) : - m_handle(h) + process(id) { if (fhstdin.is_valid()) m_sstdin.reset(new postream(fhstdin)); @@ -229,16 +186,6 @@ // ------------------------------------------------------------------------ inline -child::handle_type -child::get_handle(void) - const -{ - return m_handle; -} - -// ------------------------------------------------------------------------ - -inline postream& child::get_stdin(void) const @@ -272,24 +219,30 @@ // ------------------------------------------------------------------------ inline -status +const status child::wait(void) { #if defined(BOOST_PROCESS_POSIX_API) int s; - if (::waitpid(m_handle, &s, 0) == -1) + if (::waitpid(get_id(), &s, 0) == -1) boost::throw_exception (system_error("boost::process::child::wait", "waitpid(2) failed", errno)); return status(s); #elif defined(BOOST_PROCESS_WIN32_API) DWORD code; + HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, + FALSE, get_id()); + if (h == INVALID_HANDLE_VALUE) + boost::throw_exception + (system_error("boost::process::child::wait", + "OpenProcess failed", ::GetLastError())); // XXX This loop should go away in favour of a passive wait. do { - ::GetExitCodeProcess(m_handle, &code); + ::GetExitCodeProcess(h, &code); ::Sleep(500); } while (code == STILL_ACTIVE); - ::WaitForSingleObject(m_handle, 0); + ::WaitForSingleObject(h, 0); return status(code); #endif } Only in ./process: children.hpp Only in ./process: command_line.hpp diff -ru ./process/config.hpp /home/cfairles/src/skotty/boost/process/config.hpp --- ./process/config.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/config.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -74,6 +49,9 @@ //! procedure management needs to follow Unix semantics. //! # define BOOST_PROCESS_POSIX_API + #endif +#include "boost/process/detail/config.hpp" + #endif // !defined(BOOST_PROCESS_CONFIG_HPP) Only in /home/cfairles/src/skotty/boost/process: context.hpp Only in ./process/detail: command_line_ops.hpp Only in /home/cfairles/src/skotty/boost/process/detail: config.hpp Only in ./process/detail: environment.hpp Only in ./process/detail: factories.hpp diff -ru ./process/detail/file_handle.hpp /home/cfairles/src/skotty/boost/process/detail/file_handle.hpp --- ./process/detail/file_handle.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/file_handle.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -45,7 +20,7 @@ #define BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) extern "C" { @@ -61,7 +36,7 @@ #endif #include -#include +#include "boost/process/exceptions.hpp" #include namespace boost { @@ -330,31 +305,21 @@ mutable handle_type m_handle; //! - //! \brief Constant representing an invalid handle value. + //! \brief Constant function representing an invalid handle value. //! -#if defined(BOOST_PROCESS_DOXYGEN) - static const handle_type INVALID_VALUE = -1; -#elif defined(BOOST_PROCESS_POSIX_API) - static const handle_type INVALID_VALUE = -1; -#elif defined(BOOST_PROCESS_WIN32_API) - static const handle_type INVALID_VALUE; -#endif + //! Returns the platform-specific handle value that represents an + //! invalid handle. This is a constant function rather than a regular + //! constant because, in the latter case, we cannot define it under + //! Win32 due to the value being of a complex type. + //! + static const handle_type invalid_value(void); }; // ------------------------------------------------------------------------ -// XXX No, no, no! This is incorrect as it will cause conflicts if this -// file is included in two different compilation units... -#if defined(BOOST_PROCESS_WIN32_API) -const file_handle::handle_type file_handle::INVALID_VALUE = - INVALID_HANDLE_VALUE; -#endif - -// ------------------------------------------------------------------------ - inline file_handle::file_handle(void) : - m_handle(INVALID_VALUE) + m_handle(invalid_value()) { } @@ -364,7 +329,7 @@ file_handle::file_handle(handle_type h) : m_handle(h) { - BOOST_ASSERT(m_handle != INVALID_VALUE); + BOOST_ASSERT(m_handle != invalid_value()); } // ------------------------------------------------------------------------ @@ -373,7 +338,7 @@ file_handle::file_handle(const file_handle& fh) : m_handle(fh.m_handle) { - fh.m_handle = INVALID_VALUE; + fh.m_handle = invalid_value(); } // ------------------------------------------------------------------------ @@ -392,7 +357,7 @@ file_handle::operator=(const file_handle& fh) { m_handle = fh.m_handle; - fh.m_handle = INVALID_VALUE; + fh.m_handle = invalid_value(); return *this; } @@ -404,7 +369,7 @@ file_handle::is_valid(void) const { - return m_handle != INVALID_VALUE; + return m_handle != invalid_value(); } // ------------------------------------------------------------------------ @@ -421,7 +386,7 @@ ::CloseHandle(m_handle); #endif - m_handle = INVALID_VALUE; + m_handle = invalid_value(); } // ------------------------------------------------------------------------ @@ -433,7 +398,7 @@ BOOST_ASSERT(is_valid()); handle_type h = m_handle; - m_handle = INVALID_VALUE; + m_handle = invalid_value(); return h; } @@ -552,6 +517,19 @@ // ------------------------------------------------------------------------ +inline +const file_handle::handle_type +file_handle::invalid_value(void) +{ +#if defined(BOOST_PROCESS_POSIX_API) + return -1; +#elif defined(BOOST_PROCESS_WIN32_API) + return INVALID_HANDLE_VALUE; +#endif +} + +// ------------------------------------------------------------------------ + } // namespace detail } // namespace process } // namespace boost Only in ./process/detail: launcher_base.hpp diff -ru ./process/detail/pipe.hpp /home/cfairles/src/skotty/boost/process/detail/pipe.hpp --- ./process/detail/pipe.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/pipe.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -45,11 +20,14 @@ #define BOOST_PROCESS_DETAIL_PIPE_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) extern "C" { # include +# ifdef USE_NONBLOCKING_READ_PIPE +# include +# endif } # include #elif defined(BOOST_PROCESS_WIN32_API) @@ -60,8 +38,8 @@ # error "Unsupported platform." #endif -#include -#include +#include "boost/process/detail/file_handle.hpp" +#include "boost/process/exceptions.hpp" #include namespace boost { @@ -164,8 +142,15 @@ boost::throw_exception (system_error("boost::process::detail::pipe::pipe", "pipe(2) failed", errno)); + +#ifdef USE_NONBLOCKING_READ_PIPE + if (::fcntl(hs[0], F_SETFL, O_NONBLOCK) == -1) + boost::throw_exception + (system_error("boost::process::detail::pipe::pipe", + "fcntl(2) failed", errno)); +#endif + #endif - m_read_end = file_handle(hs[0]); m_write_end = file_handle(hs[1]); } diff -ru ./process/detail/posix_ops.hpp /home/cfairles/src/skotty/boost/process/detail/posix_ops.hpp --- ./process/detail/posix_ops.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/posix_ops.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -45,7 +20,11 @@ #define BOOST_PROCESS_DETAIL_POSIX_OPS_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" + +extern "C" { +# include +} #if !defined(BOOST_PROCESS_POSIX_API) # error "Unsupported platform." @@ -54,40 +33,115 @@ extern "C" { # include # include +# include } #include #include +#include +#include #include #include +#include #include -#include -#include -#include -#include -#include -#include -#include +#include "boost/process/detail/file_handle.hpp" +#include "boost/process/detail/pipe.hpp" +#include "boost/process/detail/stream_info.hpp" +#include "boost/process/environment.hpp" +#include "boost/process/exceptions.hpp" +#include "boost/process/stream_behavior.hpp" +#include #include namespace boost { namespace process { namespace detail { +inline long process_trace( enum __ptrace_request request, pid_t pid = 0, void *addr = 0, void *data = 0) +{ return ::ptrace(request, pid, addr, data); } + +inline long process_trace( int request, pid_t pid = 0, void *addr = 0, void *data = 0) +{ return ::ptrace((__ptrace_request)request, pid, addr, data); } + // ------------------------------------------------------------------------ //! -//! Holds a mapping between native file descriptors and their corresponding -//! pipes to set up communication between the parent and the %child process. +//! \brief Converts the command line to an array of C strings. //! -typedef std::map< int, stream_info > info_map; +//! Converts the command line's list of arguments to the format expected +//! by the \a argv parameter in the POSIX execve() system call. +//! +//! This operation is only available in POSIX systems. +//! +//! \return The first argument of the pair is an integer that indicates +//! how many strings are stored in the second argument. The +//! second argument is a NULL-terminated, dynamically allocated +//! vector of dynamically allocated strings holding the arguments +//! to the executable. The caller is responsible of freeing them. +//! +template< class Arguments > +inline +std::pair< std::size_t, char** > +collection_to_posix_argv(const Arguments& args) +{ + std::size_t nargs = args.size(); + BOOST_ASSERT(nargs > 0); + + char** argv = new char*[nargs + 1]; + typename Arguments::size_type i = 0; + for (typename Arguments::const_iterator iter = args.begin(); + iter != args.end(); iter++) { + argv[i] = ::strdup((*iter).c_str()); + i++; + } + argv[nargs] = NULL; + + return std::pair< std::size_t, char ** >(nargs, argv); +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Converts an environment to a char** table as used by execve(). +//! +//! Converts the environment's contents to the format used by the +//! execve() system call. The returned char** array is allocated +//! in dynamic memory and the caller must free it when not used any +//! more. Each entry is also allocated in dynamic memory and is a +//! null-terminated string of the form var=value; these must also be +//! released by the caller. +//! +inline +char** +environment_to_envp(const environment& env) +{ + char** ep = new char*[env.size() + 1]; + + environment::size_type i = 0; + for (environment::const_iterator iter = env.begin(); + iter != env.end(); iter++) { + std::string tmp = (*iter).first + "=" + (*iter).second; + + char* cstr = new char[tmp.length() + 1]; + std::strncpy(cstr, tmp.c_str(), tmp.length()); + cstr[tmp.length()] = '\0'; + + ep[i++] = cstr; + } + + ep[i] = NULL; + + return ep; +} + +// ------------------------------------------------------------------------ //! -//! Maintains a list of file descriptor pairs, aimed at keeping a list of -//! stream merges (source descriptor, target descriptor). +//! Holds a mapping between native file descriptors and their corresponding +//! pipes to set up communication between the parent and the %child process. //! -typedef std::set< std::pair< int, int > > merge_set; +typedef std::map< int, stream_info > info_map; // ------------------------------------------------------------------------ @@ -151,7 +205,14 @@ //! before execution. Empty if this feature is not desired. //! std::string m_chroot; - + + struct rlimit m_cpu_time_limit; + struct rlimit m_file_size_limit; + struct rlimit m_address_space_limit; + struct rlimit m_file_descriptor_limit; + unsigned int m_alarm_signal_duration; + bool m_set_ptrace; + //! //! \brief Creates a new properties set. //! @@ -181,12 +242,22 @@ m_uid(::getuid()), m_euid(::geteuid()), m_gid(::getgid()), - m_egid(::getegid()) + m_egid(::getegid()), + m_alarm_signal_duration(0), + m_set_ptrace(false) { + ::getrlimit(RLIMIT_CPU, &m_cpu_time_limit); + ::getrlimit(RLIMIT_AS, &m_address_space_limit); + ::getrlimit(RLIMIT_FSIZE, &m_file_size_limit); + ::getrlimit(RLIMIT_NOFILE, &m_file_descriptor_limit); } // ------------------------------------------------------------------------ +inline bool operator!=(struct rlimit const& r1, struct rlimit const& r2) { + return (r1.rlim_cur != r2.rlim_cur) || (r1.rlim_max != r2.rlim_max); +} + inline void posix_setup::operator()(void) @@ -213,25 +284,50 @@ "setegid(2) failed", errno)); } - if (m_uid != ::getuid()) { - if (::setuid(m_uid) == -1) - boost::throw_exception - (system_error("boost::process::detail::posix_setup", - "setuid(2) failed", errno)); - } - if (m_euid != ::geteuid()) { if (::seteuid(m_euid) == -1) boost::throw_exception (system_error("boost::process::detail::posix_setup", "seteuid(2) failed", errno)); } + + if (m_uid != ::getuid()) { + if (::setuid(m_uid) == -1) + boost::throw_exception + (system_error("boost::process::detail::posix_setup", + "setuid(2) failed", errno)); + } BOOST_ASSERT(m_work_directory != ""); if (chdir(m_work_directory.c_str()) == -1) boost::throw_exception (system_error("boost::process::detail::posix_setup", "chdir(2) failed", errno)); + + + if(::setrlimit(RLIMIT_CPU, &m_cpu_time_limit) == -1) { + boost::throw_exception + (system_error("boost::process::detail::posix_setup", + "setrlimit(2) failed", errno)); + } + + if(::setrlimit(RLIMIT_AS, &m_address_space_limit) == -1) { + boost::throw_exception + (system_error("boost::process::detail::posix_setup", + "setrlimit(2) failed", errno)); + } + + if(::setrlimit(RLIMIT_FSIZE, &m_file_size_limit) == -1) { + boost::throw_exception + (system_error("boost::process::detail::posix_setup", + "setrlimit(2) failed", errno)); + } + + if(::setrlimit(RLIMIT_NOFILE, &m_file_descriptor_limit) == -1) { + boost::throw_exception + (system_error("boost::process::detail::posix_setup", + "setrlimit(2) failed", errno)); + } } // ------------------------------------------------------------------------ @@ -251,7 +347,7 @@ //! inline void -setup_input(info_map& info, bool closeflags[], int maxdescs) +setup_input(info_map& info, bool* closeflags, int maxdescs) { for (info_map::iterator iter = info.begin(); iter != info.end(); iter++) { int d = (*iter).first; @@ -260,7 +356,7 @@ BOOST_ASSERT(d < maxdescs); closeflags[d] = false; - if (si.m_type == stream_info::usefile) { + if (si.m_type == stream_info::use_file) { int fd = ::open(si.m_file.c_str(), O_RDONLY); if (fd == -1) boost::throw_exception @@ -272,10 +368,10 @@ h.posix_remap(d); h.disown(); } - } else if (si.m_type == stream_info::usehandle) { + } else if (si.m_type == stream_info::use_handle) { if (si.m_handle.get() != d) si.m_handle.posix_remap(d); - } else if (si.m_type == stream_info::usepipe) { + } else if (si.m_type == stream_info::use_pipe) { si.m_pipe->wend().close(); if (d != si.m_pipe->rend().get()) si.m_pipe->rend().posix_remap(d); @@ -290,9 +386,9 @@ //! \brief Configures child process' output streams. //! //! Sets up the current process' output streams to behave according to the -//! information in the \a info map and in the \a merges set. \a closeflags -//! is modified to reflect those descriptors that should not be closed -//! because they where modified by the function. +//! information in the \a info map. \a closeflags is modified to reflect +//! those descriptors that should not be closed because they where modified +//! by the function. //! //! Modifies the current execution environment, so this should only be run //! on the child process after the fork(2) has happened. @@ -301,8 +397,7 @@ //! inline void -setup_output(info_map& info, merge_set& merges, bool closeflags[], - int maxdescs) +setup_output(info_map& info, bool* closeflags, int maxdescs) { for (info_map::iterator iter = info.begin(); iter != info.end(); iter++) { int d = (*iter).first; @@ -311,7 +406,12 @@ BOOST_ASSERT(d < maxdescs); closeflags[d] = false; - if (si.m_type == stream_info::usefile) { + if (si.m_type == stream_info::redirect) { + // Handled once all other descriptors have been configured. + // XXX This is most likely a hack begging for problems. + // Should replace info_map with another collection that + // respects ordering so that the user can control this. + } else if (si.m_type == stream_info::use_file) { int fd = ::open(si.m_file.c_str(), O_WRONLY); if (fd == -1) boost::throw_exception @@ -323,10 +423,10 @@ h.posix_remap(d); h.disown(); } - } else if (si.m_type == stream_info::usehandle) { + } else if (si.m_type == stream_info::use_handle) { if (si.m_handle.get() != d) si.m_handle.posix_remap(d); - } else if (si.m_type == stream_info::usepipe) { + } else if (si.m_type == stream_info::use_pipe) { si.m_pipe->rend().close(); if (d != si.m_pipe->wend().get()) si.m_pipe->wend().posix_remap(d); @@ -334,13 +434,12 @@ BOOST_ASSERT(si.m_type == stream_info::inherit); } - for (merge_set::const_iterator iter = merges.begin(); - iter != merges.end(); iter++) { - const std::pair< int, int >& p = (*iter); - file_handle fh = file_handle::posix_dup(p.second, p.first); - fh.disown(); - BOOST_ASSERT(p.first < maxdescs); - closeflags[p.first] = false; + for (info_map::iterator iter = info.begin(); iter != info.end(); iter++) { + int d = (*iter).first; + stream_info& si = (*iter).second; + + if (si.m_type == stream_info::redirect) + file_handle::posix_dup(si.m_desc_to, d).disown(); } } @@ -361,22 +460,21 @@ //! redirected. //! \param infoout A map describing all output file descriptors to be //! redirected. -//! \param merges A list of output file descriptors to be merged. //! \param setup A helper object used to configure the child's execution //! environment. //! \return The new process' PID. The caller is responsible of creating //! an appropriate Child representation for it. //! -template< class Command_Line > +template< class Executable, class Arguments > inline pid_t -posix_start(const Command_Line& cl, +posix_start(const Executable& exe, + const Arguments& args, const environment& env, info_map& infoin, info_map& infoout, - merge_set& merges, const posix_setup& setup) -{ +{ pid_t pid = ::fork(); if (pid == -1) { boost::throw_exception @@ -389,15 +487,15 @@ int maxdescs = 128; // XXX #endif try { - bool closeflags[maxdescs]; + boost::scoped_array< bool > closeflags(new bool[maxdescs]); for (int i = 0; i < maxdescs; i++) - closeflags[i] = true; + closeflags.get()[i] = true; - setup_input(infoin, closeflags, maxdescs); - setup_output(infoout, merges, closeflags, maxdescs); + setup_input(infoin, closeflags.get(), maxdescs); + setup_output(infoout, closeflags.get(), maxdescs); for (int i = 0; i < maxdescs; i++) - if (closeflags[i]) + if (closeflags.get()[i]) ::close(i); setup(); @@ -407,16 +505,24 @@ ::exit(EXIT_FAILURE); } - std::pair< std::size_t, char** > args = command_line_to_posix_argv(cl); - char** envp = env.envp(); - - ::execve(cl.get_executable().c_str(), args.second, envp); + std::pair< std::size_t, char** > argcv = + collection_to_posix_argv(args); + char** envp = environment_to_envp(env); + + + //ptrace + if(setup.m_set_ptrace) process_trace(PTRACE_TRACEME, 0, NULL, NULL); + + //start alarm, must come after ptrace ?? why? + if(setup.m_alarm_signal_duration) ::alarm(setup.m_alarm_signal_duration); + + ::execve(exe.c_str(), argcv.second, envp); system_error e("boost::process::detail::posix_start", "execve(2) failed", errno); - for (std::size_t i = 0; i < args.first; i++) - delete [] args.second[i]; - delete [] args.second; + for (std::size_t i = 0; i < argcv.first; i++) + delete [] argcv.second[i]; + delete [] argcv.second; for (std::size_t i = 0; i < env.size(); i++) delete [] envp[i]; @@ -433,7 +539,7 @@ iter != infoin.end(); iter++) { stream_info& si = (*iter).second; - if (si.m_type == stream_info::usepipe) + if (si.m_type == stream_info::use_pipe) si.m_pipe->rend().close(); } @@ -441,48 +547,16 @@ iter != infoout.end(); iter++) { stream_info& si = (*iter).second; - if (si.m_type == stream_info::usepipe) + if (si.m_type == stream_info::use_pipe) si.m_pipe->wend().close(); - } - + } + return pid; } // ------------------------------------------------------------------------ //! -//! \brief Converts a stream_behavior to a info_map entry. -//! -//! Given a stream_behavior \a beh, a file descriptor \a desc and whether -//! it is an input flow on an output one (\a out), inserts the appropriate -//! information representing this stream in the \a info map. -//! -inline -void -posix_behavior_to_info(stream_behavior beh, int desc, bool out, - info_map& info) -{ - if (beh == inherit_stream) { - stream_info si; - si.m_type = stream_info::inherit; - info.insert(info_map::value_type(desc, si)); - } else if (beh == silent_stream) { - stream_info si; - si.m_type = stream_info::usefile; - si.m_file = out ? "/dev/null" : "/dev/zero"; - info.insert(info_map::value_type(desc, si)); - } else if (beh == redirect_stream) { - stream_info si; - si.m_type = stream_info::usepipe; - si.m_pipe = pipe(); - info.insert(info_map::value_type(desc, si)); - } else - BOOST_ASSERT(beh == close_stream); -} - -// ------------------------------------------------------------------------ - -//! //! \brief Locates a communication pipe and returns one of its endpoints. //! //! Given a \a info map, and a file descriptor \a desc, searches for its @@ -507,9 +581,11 @@ if (iter != info.end()) { BOOST_ASSERT(iter != info.end()); stream_info& si = (*iter).second; - BOOST_ASSERT(si.m_type == stream_info::usepipe); - fh = out ? si.m_pipe->rend().disown() : si.m_pipe->wend().disown(); - BOOST_ASSERT(fh.is_valid()); + // XXX This conditional was an assertion; should it be? + if (si.m_type == stream_info::use_pipe) { + fh = out ? si.m_pipe->rend().disown() : si.m_pipe->wend().disown(); + BOOST_ASSERT(fh.is_valid()); + } info.erase(iter); } diff -ru ./process/detail/stream_info.hpp /home/cfairles/src/skotty/boost/process/detail/stream_info.hpp --- ./process/detail/stream_info.hpp 2006-08-21 07:45:28.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/stream_info.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -46,9 +21,11 @@ #include +#include #include -#include -#include +#include "boost/process/detail/file_handle.hpp" +#include "boost/process/detail/pipe.hpp" +#include "boost/process/stream_behavior.hpp" namespace boost { namespace process { @@ -60,26 +37,112 @@ //! \brief Configuration data for a file descriptor. //! //! This convenience structure provides a compact way to pass information -//! around on how to configure a file descriptor. It is used in -//! conjunction with the info_map map to create an unidirectional -//! association between file descriptors and their configuration details. +//! around on how to configure a file descriptor. It is a lower-level +//! representation of stream_behavior, as it can hold the same information +//! but in a way that can be used by the underlying operating system. //! struct stream_info { - enum type { close, inherit, usefile, usehandle, usepipe } m_type; + enum type { + //! + //! \brief Matches stream_behavior::close. + //! + close, + + //! + //! \brief Matches stream_behavior::inherit. + //! + inherit, + + //! + //! \brief Matches stream_behavior::redirect_to_stdout and + //! stream_behavior::posix_redirect. + //! + redirect, + + //! + //! \brief Matches stream_behavior::silence. + //! + use_file, + + //! + //! \brief Matches NOTHING YET. XXX. + //! + use_handle, + + //! + //! \brief Matches stream_behavior::capture. + //! + use_pipe + }; + enum type m_type; + + // Valid when m_type == redirect. + int m_desc_to; - // Valid when m_type == usefile. + // Valid when m_type == use_file. std::string m_file; - // Valid when m_type == usehandle. + // Valid when m_type == use_handle. file_handle m_handle; - // Valid when m_type == usepipe. + // Valid when m_type == use_pipe. boost::optional< pipe > m_pipe; + + stream_info(const stream_behavior& sb, bool out); }; // ------------------------------------------------------------------------ +inline +stream_info::stream_info(const stream_behavior& sb, bool out) +{ + switch (sb.m_type) { + case stream_behavior::capture: + m_type = use_pipe; + m_pipe = pipe(); + break; + + case stream_behavior::close: + m_type = close; + break; + + case stream_behavior::inherit: + m_type = inherit; + break; + +#if defined(BOOST_PROCESS_POSIX_API) + case stream_behavior::posix_redirect: + m_type = redirect; + m_desc_to = sb.m_desc_to; + break; +#endif + + case stream_behavior::redirect_to_stdout: + m_type = redirect; +#if defined(BOOST_PROCESS_POSIX_API) + m_desc_to = STDOUT_FILENO; +#elif defined(BOOST_PROCESS_WIN32_API) + m_desc_to = 1; +#endif + break; + + case stream_behavior::silence: + m_type = use_file; +#if defined(BOOST_PROCESS_POSIX_API) + m_file = out ? "/dev/null" : "/dev/zero"; +#elif defined(BOOST_PROCESS_WIN32_API) + m_file = "NUL"; +#endif + break; + + default: + BOOST_ASSERT(false); + } +} + +// ------------------------------------------------------------------------ + } // namespace detail } // namespace process } // namespace boost Only in /home/cfairles/src/skotty/boost/process/detail: .svn diff -ru ./process/detail/systembuf.hpp /home/cfairles/src/skotty/boost/process/detail/systembuf.hpp --- ./process/detail/systembuf.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/systembuf.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -45,7 +20,7 @@ #define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) extern "C" { diff -ru ./process/detail/win32_ops.hpp /home/cfairles/src/skotty/boost/process/detail/win32_ops.hpp --- ./process/detail/win32_ops.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/detail/win32_ops.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -57,14 +32,14 @@ } #include -#include -#include #include #include #include +#include #include #include #include +#include #include namespace boost { @@ -74,6 +49,111 @@ // ------------------------------------------------------------------------ //! +//! \brief Converts the command line to a plain string. +//! +//! Converts the command line's list of arguments to the format +//! expected by the \a lpCommandLine parameter in the CreateProcess() +//! system call. +//! +//! This operation is only available in Win32 systems. +//! +//! \return A dynamically allocated string holding the command line +//! to be passed to the executable. It is returned in a +//! shared_array object to ensure its release at some point. +//! +template< class Arguments > +inline +boost::shared_array< TCHAR > +collection_to_win32_cmdline(const Arguments& args) +{ + typedef std::vector< std::string > arguments_vector; + Arguments args2; + + typename Arguments::size_type i = 0; + std::size_t length = 0; + for (typename Arguments::const_iterator iter = args.begin(); + iter != args.end(); iter++) { + std::string arg = (*iter); + + std::string::size_type pos = 0; + while ((pos = arg.find('"', pos)) != std::string::npos) { + arg.replace(pos, 1, "\\\""); + pos += 2; + } + + if (arg.find(' ') != std::string::npos) + arg = '\"' + arg + '\"'; + + if (i != args.size() - 1) + arg += ' '; + + args2.push_back(arg); + length += arg.size() + 1; + + i++; + } + + boost::shared_array< TCHAR > cmdline(new TCHAR[length]); + ::_tcscpy_s(cmdline.get(), length, TEXT("")); + for (arguments_vector::size_type i = 0; i < args2.size(); i++) + ::_tcscat_s(cmdline.get(), length, TEXT(args2[i].c_str())); + + return cmdline; +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Converts an environment to a string used by CreateProcess(). +//! +//! Converts the environment's contents to the format used by the +//! CreateProcess() system call. The returned TCHAR* string is +//! allocated in dynamic memory and the caller must free it when not +//! used any more. This is enforced by the use of a shared pointer. +//! The string is of the form var1=value1\\0var2=value2\\0\\0. +//! +inline +boost::shared_array< TCHAR > +environment_to_win32_strings(const environment& env) +{ + boost::shared_array< TCHAR > strs(NULL); + + // TODO: Add the "" variable to the returned string; it shouldn't + // be in the environment if the user didn't add it. + + if (env.size() == 0) { + strs.reset(new TCHAR[2]); + ::ZeroMemory(strs.get(), sizeof(TCHAR) * 2); + } else { + std::string::size_type len = sizeof(TCHAR); + for (environment::const_iterator iter = env.begin(); + iter != env.end(); iter++) + len += ((*iter).first.length() + 1 + (*iter).second.length() + + 1) * sizeof(TCHAR); + + strs.reset(new TCHAR[len]); + + TCHAR* ptr = strs.get(); + for (environment::const_iterator iter = env.begin(); + iter != env.end(); iter++) { + std::string tmp = (*iter).first + "=" + (*iter).second; + _tcscpy_s(ptr, len - (ptr - strs.get()) * sizeof(TCHAR), + TEXT(tmp.c_str())); + ptr += (tmp.length() + 1) * sizeof(TCHAR); + + BOOST_ASSERT(static_cast< std::string::size_type > + (ptr - strs.get()) * sizeof(TCHAR) < len); + } + *ptr = '\0'; + } + + BOOST_ASSERT(strs.get() != NULL); + return strs; +} + +// ------------------------------------------------------------------------ + +//! //! \brief Helper class to configure a Win32 %child. //! //! This helper class is used to hold all the attributes that configure a @@ -125,15 +205,15 @@ //! \pre \a setup.m_startupinfo cannot have the \a STARTF_USESTDHANDLES set //! in the \a dwFlags field. //! -template< class Command_Line > +template< class Executable, class Arguments > inline PROCESS_INFORMATION -win32_start(const Command_Line& cl, +win32_start(const Executable& exe, + const Arguments& args, const environment& env, stream_info& infoin, stream_info& infoout, stream_info& infoerr, - bool merge_out_err, const win32_setup& setup) { file_handle chin, chout, cherr; @@ -149,7 +229,7 @@ if (infoin.m_type == stream_info::close) { } else if (infoin.m_type == stream_info::inherit) { chin = file_handle::win32_std(STD_INPUT_HANDLE, true); - } else if (infoin.m_type == stream_info::usefile) { + } else if (infoin.m_type == stream_info::use_file) { HANDLE h = ::CreateFile(TEXT(infoin.m_file.c_str()), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -158,10 +238,10 @@ (system_error("boost::process::detail::win32_start", "CreateFile failed", ::GetLastError())); chin = file_handle(h); - } else if (infoin.m_type == stream_info::usehandle) { + } else if (infoin.m_type == stream_info::use_handle) { chin = infoin.m_handle; chin.win32_set_inheritable(true); - } else if (infoin.m_type == stream_info::usepipe) { + } else if (infoin.m_type == stream_info::use_pipe) { infoin.m_pipe->rend().win32_set_inheritable(true); chin = infoin.m_pipe->rend(); } else @@ -171,7 +251,7 @@ if (infoout.m_type == stream_info::close) { } else if (infoout.m_type == stream_info::inherit) { chout = file_handle::win32_std(STD_OUTPUT_HANDLE, true); - } else if (infoout.m_type == stream_info::usefile) { + } else if (infoout.m_type == stream_info::use_file) { HANDLE h = ::CreateFile(TEXT(infoout.m_file.c_str()), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); @@ -180,10 +260,10 @@ (system_error("boost::process::detail::win32_start", "CreateFile failed", ::GetLastError())); chout = file_handle(h); - } else if (infoout.m_type == stream_info::usehandle) { + } else if (infoout.m_type == stream_info::use_handle) { chout = infoout.m_handle; chout.win32_set_inheritable(true); - } else if (infoout.m_type == stream_info::usepipe) { + } else if (infoout.m_type == stream_info::use_pipe) { infoout.m_pipe->wend().win32_set_inheritable(true); chout = infoout.m_pipe->wend(); } else @@ -191,13 +271,13 @@ si->hStdOutput = chout.is_valid() ? chout.get() : INVALID_HANDLE_VALUE; if (infoerr.m_type == stream_info::close) { - if (merge_out_err) { - BOOST_ASSERT(chout.is_valid()); - cherr = file_handle::win32_dup(chout.get(), true); - } } else if (infoerr.m_type == stream_info::inherit) { cherr = file_handle::win32_std(STD_ERROR_HANDLE, true); - } else if (infoerr.m_type == stream_info::usefile) { + } else if (infoerr.m_type == stream_info::redirect) { + BOOST_ASSERT(infoerr.m_desc_to == 1); + BOOST_ASSERT(chout.is_valid()); + cherr = file_handle::win32_dup(chout.get(), true); + } else if (infoerr.m_type == stream_info::use_file) { HANDLE h = ::CreateFile(TEXT(infoerr.m_file.c_str()), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); @@ -206,10 +286,10 @@ (system_error("boost::process::detail::win32_start", "CreateFile failed", ::GetLastError())); cherr = file_handle(h); - } else if (infoerr.m_type == stream_info::usehandle) { + } else if (infoerr.m_type == stream_info::use_handle) { cherr = infoerr.m_handle; cherr.win32_set_inheritable(true); - } else if (infoerr.m_type == stream_info::usepipe) { + } else if (infoerr.m_type == stream_info::use_pipe) { infoerr.m_pipe->wend().win32_set_inheritable(true); cherr = infoerr.m_pipe->wend(); } else @@ -219,13 +299,11 @@ PROCESS_INFORMATION pi; ::ZeroMemory(&pi, sizeof(pi)); - boost::shared_array< TCHAR > cmdline = - command_line_to_win32_cmdline(cl); - boost::scoped_array< TCHAR > executable - (::_tcsdup(TEXT(cl.get_executable().c_str()))); + boost::shared_array< TCHAR > cmdline = collection_to_win32_cmdline(args); + boost::scoped_array< TCHAR > executable(::_tcsdup(TEXT(exe.c_str()))); boost::scoped_array< TCHAR > workdir (::_tcsdup(TEXT(setup.m_work_directory.c_str()))); - boost::shared_array< TCHAR > envstrs = env.win32_strings(); + boost::shared_array< TCHAR > envstrs = environment_to_win32_strings(env); if (!::CreateProcess(executable.get(), cmdline.get(), NULL, NULL, TRUE, 0, envstrs.get(), workdir.get(), si.get(), &pi)) { @@ -239,42 +317,6 @@ // ------------------------------------------------------------------------ -//! -//! \brief Converts a stream_behavior to a stream_info object. -//! -//! Given a stream_behavior \a beh and whether it shall behave as an input -//! flow or as an output one (\a out), returns a stream_info object -//! representing a flow that follows the provided behavior. -//! -//! \param parentfh A reference to a file_handle that receives the handle -//! the parent can use to communicate with the child. -//! \return The new stream_info object. -//! -inline -stream_info -win32_behavior_to_info(stream_behavior beh, bool out, file_handle& parentfh) -{ - stream_info si; - - if (beh == inherit_stream) { - si.m_type = stream_info::inherit; - } else if (beh == redirect_stream) { - si.m_type = stream_info::usepipe; - si.m_pipe = pipe(); - parentfh = out ? si.m_pipe->rend() : si.m_pipe->wend(); - } else if (beh == silent_stream) { - si.m_type = stream_info::usefile; - si.m_file = "NUL"; - } else { - BOOST_ASSERT(beh == close_stream); - si.m_type = stream_info::close; - } - - return si; -} - -// ------------------------------------------------------------------------ - } // namespace detail } // namespace process } // namespace boost Only in /home/cfairles/src/skotty/boost/process: environment.hpp diff -ru ./process/exceptions.hpp /home/cfairles/src/skotty/boost/process/exceptions.hpp --- ./process/exceptions.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/exceptions.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -45,7 +20,7 @@ #define BOOST_PROCESS_EXCEPTIONS_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) # include Only in ./process: forward_decls.hpp Only in ./process: launcher.hpp Only in /home/cfairles/src/skotty/boost/process: operations.hpp Only in ./process: pipeline.hpp diff -ru ./process/pistream.hpp /home/cfairles/src/skotty/boost/process/pistream.hpp --- ./process/pistream.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/pistream.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -47,8 +22,8 @@ #include #include -#include -#include +#include "boost/process/detail/file_handle.hpp" +#include "boost/process/detail/systembuf.hpp" namespace boost { namespace process { diff -ru ./process/posix_child.hpp /home/cfairles/src/skotty/boost/process/posix_child.hpp --- ./process/posix_child.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/posix_child.hpp 2008-06-19 22:20:29.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -44,7 +19,7 @@ #define BOOST_PROCESS_POSIX_CHILD_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if !defined(BOOST_PROCESS_POSIX_API) # error "Unsupported platform." @@ -53,20 +28,21 @@ #include #include -#include -#include -#include -#include -#include +#include "boost/process/child.hpp" +#include "boost/process/detail/pipe.hpp" +#include "boost/process/detail/posix_ops.hpp" +#include "boost/process/pistream.hpp" +#include "boost/process/postream.hpp" + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#include +#else #include +#endif namespace boost { namespace process { -namespace detail { -struct factories; -} - // ------------------------------------------------------------------------ //! @@ -92,6 +68,14 @@ public child { public: +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + typedef std::shared_ptr postream_ptr; + typedef std::shared_ptr pistream_ptr; +#else + typedef boost::shared_ptr postream_ptr; + typedef boost::shared_ptr pistream_ptr; +#endif + //! //! \brief Gets a reference to the child's input stream \a desc. //! @@ -126,12 +110,12 @@ //! //! \brief Maps child's file descriptors to postream objects. //! - typedef std::map< int, boost::shared_ptr< postream > > input_map; + typedef std::map< int, postream_ptr > input_map; //! //! \brief Maps child's file descriptors to pistream objects. //! - typedef std::map< int, boost::shared_ptr< pistream > > output_map; + typedef std::map< int, pistream_ptr > output_map; //! //! \brief Contains all relationships between child's input file @@ -145,7 +129,7 @@ //! output_map m_output_map; -protected: +public: // XXX //! //! \brief Constructs a new POSIX child object representing a just //! spawned child process. @@ -163,19 +147,18 @@ //! business in creating representations of live processes himself; //! the library takes care of that in all cases. //! - posix_child(handle_type h, + posix_child(id_type id, detail::info_map& infoin, detail::info_map& infoout); - friend struct detail::factories; }; // ------------------------------------------------------------------------ inline -posix_child::posix_child(handle_type h, +posix_child::posix_child(id_type id, detail::info_map& infoin, detail::info_map& infoout) : - child(h, + child(id, posix_info_locate_pipe(infoin, STDIN_FILENO, false), posix_info_locate_pipe(infoout, STDOUT_FILENO, true), posix_info_locate_pipe(infoout, STDERR_FILENO, true)) @@ -184,9 +167,9 @@ iter != infoin.end(); iter++) { detail::stream_info& si = (*iter).second; - if (si.m_type == detail::stream_info::usepipe) { + if (si.m_type == detail::stream_info::use_pipe) { BOOST_ASSERT(si.m_pipe->wend().is_valid()); - boost::shared_ptr< postream > st(new postream(si.m_pipe->wend())); + postream_ptr st(new postream(si.m_pipe->wend())); m_input_map.insert(input_map::value_type((*iter).first, st)); } } @@ -195,9 +178,9 @@ iter != infoout.end(); iter++) { detail::stream_info& si = (*iter).second; - if (si.m_type == detail::stream_info::usepipe) { + if (si.m_type == detail::stream_info::use_pipe) { BOOST_ASSERT(si.m_pipe->rend().is_valid()); - boost::shared_ptr< pistream > st(new pistream(si.m_pipe->rend())); + pistream_ptr st(new pistream(si.m_pipe->rend())); m_output_map.insert(output_map::value_type((*iter).first, st)); } } Only in /home/cfairles/src/skotty/boost/process: posix_context.hpp Only in ./process: posix_launcher.hpp Only in /home/cfairles/src/skotty/boost/process: posix_operations.hpp Only in /home/cfairles/src/skotty/boost/process: posix_status.hpp diff -ru ./process/postream.hpp /home/cfairles/src/skotty/boost/process/postream.hpp --- ./process/postream.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/postream.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -47,8 +22,8 @@ #include #include -#include -#include +#include "boost/process/detail/file_handle.hpp" +#include "boost/process/detail/systembuf.hpp" namespace boost { namespace process { Only in /home/cfairles/src/skotty/boost/process: process.hpp Only in /home/cfairles/src/skotty/boost/process: self.hpp diff -ru ./process/status.hpp /home/cfairles/src/skotty/boost/process/status.hpp --- ./process/status.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/status.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -44,7 +19,7 @@ #define BOOST_PROCESS_STATUS_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" #if defined(BOOST_PROCESS_POSIX_API) extern "C" { @@ -66,49 +41,20 @@ //! \brief Status returned by a finalized child process. //! //! This class represents the %status returned by a child process after it -//! has terminated. It contains many methods that may make no sense in -//! some platforms, but this is done for simplicity. These methods are -//! supported everywhere, although they may simply return fake values. +//! has terminated. It only provides that information available under all +//! supported platforms. +//! +//! \see posix_status //! class status { +protected: //! - //! \brief Indicates whether the process has exited on purpose. + //! \brief OS-specific codification of exit status. //! - bool m_exited; + int m_flags; //! - //! \brief If exited, indicates the exit code. - //! - int m_exit_status; - - //! - //! \brief Indicates whether the process was signaled. - //! - bool m_signaled; - - //! - //! \brief If signaled, indicates the termination signal. - //! - int m_term_signal; - - //! - //! \brief If signaled, indicates whether the process dumped core. - //! - bool m_dumped_core; - - //! - //! \brief Indicates whether the process was stopped. - //! - bool m_stopped; - - //! - //! \brief If stopped, indicates the stop signal. - //! - int m_stop_signal; - -public: - //! //! \brief Creates a status object based on exit information. //! //! Creates a new status object representing the exit status of a @@ -119,7 +65,9 @@ //! Win32 system it contains the exit code only. //! status(int flags); + friend class child; +public: //! //! \brief Returns whether the process exited gracefully or not. //! @@ -135,81 +83,13 @@ //! \pre exited() is true. //! int exit_status(void) const; - - //! - //! \brief Returns whether the process exited due to an external - //! signal. - //! - //! Returns whether the process exited due to an external signal. - //! The result is always false in Win32 systems. - //! - bool signaled(void) const; - - //! - //! \brief If signaled, returns the terminating signal code. - //! - //! If the process was signaled, returns the terminating signal code. - //! Cannnot be called under Win32 because the preconditions will not - //! ever be met. - //! - //! \pre signaled() is true. - //! - int term_signal(void) const; - - //! - //! \brief If signaled, returns whether the process dumped core. - //! - //! If the process was signaled, returns whether the process - //! produced a core dump. - //! Cannnot be called under Win32 because the preconditions will not - //! ever be met. - //! - //! \pre signaled() is true. - //! - bool dumped_core(void) const; - - //! - //! \brief Returns whether the process was stopped by an external - //! signal. - //! - //! Returns whether the process was stopped by an external signal. - //! The result is always false in Win32 systems. - //! - bool stopped(void) const; - - //! - //! \brief If stpped, returns the stop signal code. - //! - //! If the process was stopped, returns the stop signal code. - //! Cannnot be called under Win32 because the preconditions will not - //! ever be met. - //! - //! \pre signaled() is true. - //! - int stop_signal(void) const; }; // ------------------------------------------------------------------------ inline status::status(int flags) : -#if defined(BOOST_PROCESS_POSIX_API) - m_exited(WIFEXITED(flags)), - m_exit_status(WEXITSTATUS(flags)), - m_signaled(WIFSIGNALED(flags)), - m_term_signal(WTERMSIG(flags)), - m_dumped_core(WCOREDUMP(flags)), - m_stopped(WIFSTOPPED(flags)), - m_stop_signal(WSTOPSIG(flags)) -#elif defined(BOOST_PROCESS_WIN32_API) - m_exited(true), - m_exit_status(flags), - m_signaled(false), - m_term_signal(0), - m_dumped_core(false), - m_stopped(false), - m_stop_signal(0) -#endif + m_flags(flags) { } @@ -220,7 +100,11 @@ status::exited(void) const { - return m_exited; +#if defined(BOOST_PROCESS_POSIX_API) + return WIFEXITED(m_flags); +#elif defined(BOOST_PROCESS_WIN32_API) + return true; +#endif } // ------------------------------------------------------------------------ @@ -231,60 +115,11 @@ const { BOOST_ASSERT(exited()); - return m_exit_status; -} - -// ------------------------------------------------------------------------ - -inline -bool -status::signaled(void) - const -{ - return m_signaled; -} - -// ------------------------------------------------------------------------ - -inline -int -status::term_signal(void) - const -{ - BOOST_ASSERT(signaled()); - return m_term_signal; -} - -// ------------------------------------------------------------------------ - -inline -bool -status::dumped_core(void) - const -{ - BOOST_ASSERT(signaled()); - return m_dumped_core; -} - -// ------------------------------------------------------------------------ - -inline -bool -status::stopped(void) - const -{ - return m_stopped; -} - -// ------------------------------------------------------------------------ - -inline -int -status::stop_signal(void) - const -{ - BOOST_ASSERT(stopped()); - return m_stop_signal; +#if defined(BOOST_PROCESS_POSIX_API) + return WEXITSTATUS(m_flags); +#elif defined(BOOST_PROCESS_WIN32_API) + return m_flags; +#endif } // ------------------------------------------------------------------------ diff -ru ./process/stream_behavior.hpp /home/cfairles/src/skotty/boost/process/stream_behavior.hpp --- ./process/stream_behavior.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/stream_behavior.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,40 +3,16 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! //! \file boost/process/stream_behavior.hpp //! -//! Includes the declaration of the stream_behavior enumeration. +//! Includes the declaration of the stream_behavior class and associated +//! free functions. //! #if !defined(BOOST_PROCESS_STREAM_BEHAVIOR_HPP) @@ -44,9 +20,15 @@ #define BOOST_PROCESS_STREAM_BEHAVIOR_HPP /** \endcond */ +#include "boost/process/config.hpp" + namespace boost { namespace process { +namespace detail { +struct stream_info; +} // namespace detail + // ------------------------------------------------------------------------ //! @@ -54,37 +36,257 @@ //! //! Describes the possible states for a child's communication stream. //! -enum stream_behavior { +class stream_behavior +{ +public: + enum type { + //! + //! The child's stream is connected to the parent by using an + //! anonymous pipe so that they can send and receive data to/from + //! each other. + //! + capture, + + //! + //! The child's stream is closed upon startup so that it will not + //! have any access to it. + //! + close, + + //! + //! The child's stream is connected to the same stream used by the + //! parent. In other words, the corresponding parent's stream is + //! inherited. + //! + inherit, + + //! + //! The child's stream is connected to child's standard output. + //! This is typically used when configuring the standard error + //! stream. + //! + redirect_to_stdout, + + //! + //! The child's stream is redirected to a null device so that its + //! input is always zero or its output is lost, depending on + //! whether the stream is an input or an output one. It is + //! important to notice that this is different from close because + //! the child is still able to write data. If we closed, e.g. + //! stdout, the child might not work at all! + //! + silence, + +#if defined(BOOST_PROCESS_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) + //! + //! The child redirects the stream's output to the provided file + //! descriptor. This is a generalization of the portable + //! redirect_to_stdout behavior. + //! + posix_redirect +#endif + }; + //! - //! The stream is closed and hence the child process will not be - //! allowed to access it. + //! \brief Constructs a new stream behavior of type close. //! - close_stream, + //! This public constructor creates a new stream behavior that defaults + //! to the close behavior. In general, you will want to use the + //! available free functions to construct a stream behavior (including + //! the close one). + //! + stream_behavior(void); //! - //! The child inherits the parent's handle for the data flow, thus - //! effectively sharing it between the two processes. + //! \brief Returns this stream behavior's type. + //! + //! Returns the type of this stream behavior object. //! - inherit_stream, + type get_type(void) const; +private: //! - //! The child is connected to the parent so that they can send and - //! receive data through the stream. + //! \brief This stream's behavior type. //! - redirect_stream, + enum type m_type; +#if defined(BOOST_PROCESS_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) + // Valid when m_type == posix_redirect. + int m_desc_to; +#endif + + //! + //! \brief Constructs a new stream behavior of type \a t. //! - //! The child's stream is redirected to a null device so that its - //! output is lost. It is important to see that this is different to - //! close_stream because the child is still able to write data. If we - //! closed, e.g. stdout, it's most likely that the child couldn't work - //! at all! + //! Constructs a new stream behavior of type \a t. It is the + //! responsibility of the caller to fill in any other attributes + //! required by the specified type, if any. //! - silent_stream + stream_behavior(type t); + + // detail::stream_info provides a lower-level representation of + // stream_behavior. It is allowed to freely access this class' + // contents for simplicity. + friend struct detail::stream_info; + + // Pseudo-constructors for each stream_behavior type. These are + // needed because some types need to store additional information and + // we must ensure it is initialized appropriately. We would have used + // a class hierarchy to represent this fact, but this could cause + // problems when passing around regular objects (not pointers). + // + // XXX Individual classes look saner to me so it is worth to + // investigate that design and see if it is possible to implement + // without pointers. As long as the classes are named the same as the + // functions below, user code will require no changes. + friend inline stream_behavior capture_stream(void); + friend inline stream_behavior close_stream(void); + friend inline stream_behavior inherit_stream(void); + friend inline stream_behavior redirect_stream_to_stdout(void); + friend inline stream_behavior silence_stream(void); +#if defined(BOOST_PROCESS_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) + friend inline stream_behavior posix_redirect_stream(int to); +#endif }; // ------------------------------------------------------------------------ +inline +stream_behavior::stream_behavior(void) : + m_type(stream_behavior::close) +{ +} + +// ------------------------------------------------------------------------ + +inline +stream_behavior::stream_behavior(stream_behavior::type t) : + m_type(t) +{ +} + +// ------------------------------------------------------------------------ + +inline +stream_behavior::type +stream_behavior::get_type(void) + const +{ + return m_type; +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Creates a new stream_behavior of type stream_behavior::capture. +//! +//! Creates a new stream_behavior of type stream_behavior::capture, +//! meaning that the child's stream is connected to the parent by using an +//! anonymous pipe so that they can send and receive data to/from each +//! other. +//! +inline +stream_behavior +capture_stream(void) +{ + return stream_behavior(stream_behavior::capture); +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Creates a new stream_behavior of type stream_behavior::close. +//! +//! Creates a new stream_behavior of type stream_behavior::close, +//! meaning that the child's stream is closed upon startup so that it +//! will not have any access to it. +//! +inline +stream_behavior +close_stream(void) +{ + return stream_behavior(stream_behavior::close); +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Creates a new stream_behavior of type stream_behavior::inherit. +//! +//! Creates a new stream_behavior of type stream_behavior::inherit, +//! meaning that the child's stream is connected to the same stream used +//! by the parent. In other words, the corresponding parent's stream is +//! inherited. +//! +inline +stream_behavior +inherit_stream(void) +{ + return stream_behavior(stream_behavior::inherit); +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Creates a new stream_behavior of type +//! stream_behavior::redirect_to_stdout. +//! +//! Creates a new stream_behavior of type +//! stream_behavior::redirect_to_stdout, meaning that the child's stream is +//! connected to child's standard output. This is typically used when +//! configuring the standard error stream. +//! +inline +stream_behavior +redirect_stream_to_stdout(void) +{ + return stream_behavior(stream_behavior::redirect_to_stdout); +} + +// ------------------------------------------------------------------------ + +//! +//! \brief Creates a new stream_behavior of type stream_behavior::silence. +//! +//! Creates a new stream_behavior of type stream_behavior::capture, +//! meaning that the child's stream is redirected to a null device so that +//! its input is always zero or its output is lost, depending on whether +//! the stream is an input or an output one. It is important to notice +//! that this is different from close because the child is still able to +//! write data. If we closed, e.g. stdout, the child might not work at +//! all! +//! +inline +stream_behavior +silence_stream(void) +{ + return stream_behavior(stream_behavior::silence); +} + +// ------------------------------------------------------------------------ + +#if defined(BOOST_PROCESS_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) +//! +//! \brief Creates a new stream_behavior of type +//! stream_behavior::posix_redirect. +//! +//! Creates a new stream_behavior of type stream_behavior::posix_redirect, +//! meaning that the child's stream is redirected to the \a to child's +//! file descriptor. This is a generalization of the portable +//! redirect_stream_to_stdout() behavior. +//! +inline +stream_behavior +posix_redirect_stream(int to) +{ + stream_behavior sb(stream_behavior::posix_redirect); + sb.m_desc_to = to; + return sb; +} +#endif + +// ------------------------------------------------------------------------ + } // namespace process } // namespace boost Only in /home/cfairles/src/skotty/boost/process: .svn diff -ru ./process/win32_child.hpp /home/cfairles/src/skotty/boost/process/win32_child.hpp --- ./process/win32_child.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process/win32_child.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -59,10 +34,6 @@ namespace boost { namespace process { -namespace detail { -struct factories; -} - // ------------------------------------------------------------------------ //! @@ -92,7 +63,7 @@ //! PROCESS_INFORMATION m_process_information; -protected: +public: // XXX //! //! \brief Constructs a new Win32 child object representing a just //! spawned child process. @@ -113,19 +84,18 @@ detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr); - friend struct detail::factories; public: //! - //! \brief Returns the process' identifier. + //! \brief Returns the process' handle. //! - //! Returns a system-wide value that identifies the process. This is - //! the value of the \a dwProcessId field in the PROCESS_INFORMATION - //! structure returned by CreateProcess(). + //! Returns a process-specific handle that can be used to access the + //! process. This is the value of the \a hProcess field in the + //! PROCESS_INFORMATION structure returned by CreateProcess(). //! - //! \see get_handle() + //! \see get_id() //! - DWORD get_id(void) const; + HANDLE get_handle(void) const; //! //! \brief Returns the primary thread's handle. @@ -157,7 +127,7 @@ detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr) : - child(pi.hProcess, fhstdin, fhstdout, fhstderr), + child(pi.dwProcessId, fhstdin, fhstdout, fhstderr), m_process_information(pi) { } @@ -165,11 +135,11 @@ // ------------------------------------------------------------------------ inline -DWORD -win32_child::get_id(void) +HANDLE +win32_child::get_handle(void) const { - return m_process_information.dwProcessId; + return m_process_information.hProcess; } // ------------------------------------------------------------------------ Only in /home/cfairles/src/skotty/boost/process: win32_context.hpp Only in ./process: win32_launcher.hpp Only in /home/cfairles/src/skotty/boost/process: win32_operations.hpp diff -ru ./process.hpp /home/cfairles/src/skotty/boost/process.hpp --- ./process.hpp 2006-08-21 07:43:22.000000000 -0400 +++ /home/cfairles/src/skotty/boost/process.hpp 2008-06-13 19:09:33.000000000 -0400 @@ -3,34 +3,9 @@ // // Copyright (c) 2006 Julio M. Merino Vidal. // -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt.) // //! @@ -47,25 +22,29 @@ #define BOOST_PROCESS_HPP /** \endcond */ -#include +#include "boost/process/config.hpp" + +// XXX Reenable commented out files. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +//#include +#include "boost/process/child.hpp" +#include "boost/process/context.hpp" +#include "boost/process/operations.hpp" +#include "boost/process/pistream.hpp" +#include "boost/process/postream.hpp" +#include "boost/process/process.hpp" +#include "boost/process/self.hpp" +#include "boost/process/status.hpp" #if defined(BOOST_PROCESS_POSIX_API) -# include -# include +# include "boost/process/posix_child.hpp" +# include "boost/process/posix_context.hpp" +# include "boost/process/posix_operations.hpp" +# include "boost/process/posix_status.hpp" #elif defined(BOOST_PROCESS_WIN32_API) # include -# include +# include +# include #else # error "Unsupported platform." #endif Only in /home/cfairles/src/skotty/boost/: .svn