You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
6.2 KiB
200 lines
6.2 KiB
//
|
|
// Boost.Process
|
|
// ~~~~~~~~~~~~~
|
|
//
|
|
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
//
|
|
// 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/child.hpp
|
|
*
|
|
* Includes the declaration of the child class.
|
|
*/
|
|
|
|
#ifndef BOOST_PROCESS_CHILD_HPP
|
|
#define BOOST_PROCESS_CHILD_HPP
|
|
|
|
#include <boost/process/config.hpp>
|
|
|
|
#if defined(BOOST_POSIX_API)
|
|
# include <sys/types.h>
|
|
# include <sys/wait.h>
|
|
# include <cerrno>
|
|
#elif defined(BOOST_WINDOWS_API)
|
|
# include <windows.h>
|
|
#else
|
|
# error "Unsupported platform."
|
|
#endif
|
|
|
|
#include <boost/process/process.hpp>
|
|
#include <boost/process/pistream.hpp>
|
|
#include <boost/process/postream.hpp>
|
|
#include <boost/process/status.hpp>
|
|
#include <boost/process/detail/file_handle.hpp>
|
|
#include <boost/system/system_error.hpp>
|
|
#include <boost/throw_exception.hpp>
|
|
#include <boost/shared_ptr.hpp>
|
|
#include <boost/assert.hpp>
|
|
#include <vector>
|
|
|
|
namespace boost {
|
|
namespace process {
|
|
|
|
/**
|
|
* Generic implementation of the Child concept.
|
|
*
|
|
* The child class implements the Child concept in an operating system
|
|
* agnostic way.
|
|
*/
|
|
class child : public process
|
|
{
|
|
public:
|
|
/**
|
|
* Gets a reference to the child's standard input stream.
|
|
*
|
|
* Returns a reference to a postream object that represents the
|
|
* standard input communication channel with the child process.
|
|
*/
|
|
postream &get_stdin() const
|
|
{
|
|
BOOST_ASSERT(stdin_);
|
|
|
|
return *stdin_;
|
|
}
|
|
|
|
/**
|
|
* Gets a reference to the child's standard output stream.
|
|
*
|
|
* Returns a reference to a pistream object that represents the
|
|
* standard output communication channel with the child process.
|
|
*/
|
|
pistream &get_stdout() const
|
|
{
|
|
BOOST_ASSERT(stdout_);
|
|
|
|
return *stdout_;
|
|
}
|
|
|
|
/**
|
|
* Gets a reference to the child's standard error stream.
|
|
*
|
|
* Returns a reference to a pistream object that represents the
|
|
* standard error communication channel with the child process.
|
|
*/
|
|
pistream &get_stderr() const
|
|
{
|
|
BOOST_ASSERT(stderr_);
|
|
|
|
return *stderr_;
|
|
}
|
|
|
|
/**
|
|
* Blocks and waits for the child process to terminate.
|
|
*
|
|
* Returns a status object that represents the child process'
|
|
* finalization condition. The child process object ceases to be
|
|
* valid after this call.
|
|
*
|
|
* \remark Blocking remarks: This call blocks if the child
|
|
* process has not finalized execution and waits until
|
|
* it terminates.
|
|
*/
|
|
status wait()
|
|
{
|
|
#if defined(BOOST_POSIX_API)
|
|
int s;
|
|
if (::waitpid(get_id(), &s, 0) == -1)
|
|
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::child::wait: waitpid(2) failed"));
|
|
return status(s);
|
|
#elif defined(BOOST_WINDOWS_API)
|
|
::WaitForSingleObject(process_handle_.get(), INFINITE);
|
|
DWORD code;
|
|
if (!::GetExitCodeProcess(process_handle_.get(), &code))
|
|
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::child::wait: GetExitCodeProcess failed"));
|
|
return status(code);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Creates a new child object that represents the just spawned child
|
|
* process \a id.
|
|
*
|
|
* The \a fhstdin, \a fhstdout and \a fhstderr file handles represent
|
|
* the parent's handles used to communicate with the corresponding
|
|
* data streams. They needn't be valid but their availability must
|
|
* match the redirections configured by the launcher that spawned this
|
|
* process.
|
|
*
|
|
* The \a fhprocess handle represents a handle to the child process.
|
|
* It is only used on Windows as the implementation of wait() needs a
|
|
* process handle.
|
|
*/
|
|
child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle())
|
|
: process(id)
|
|
#if defined(BOOST_WINDOWS_API)
|
|
, process_handle_(fhprocess.release(), ::CloseHandle)
|
|
#endif
|
|
{
|
|
if (fhstdin.valid())
|
|
stdin_.reset(new postream(fhstdin));
|
|
if (fhstdout.valid())
|
|
stdout_.reset(new pistream(fhstdout));
|
|
if (fhstderr.valid())
|
|
stderr_.reset(new pistream(fhstderr));
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* The standard input stream attached to the child process.
|
|
*
|
|
* This postream object holds the communication channel with the
|
|
* child's process standard input. It is stored in a pointer because
|
|
* this field is only valid when the user requested to redirect this
|
|
* data stream.
|
|
*/
|
|
boost::shared_ptr<postream> stdin_;
|
|
|
|
/**
|
|
* The standard output stream attached to the child process.
|
|
*
|
|
* This postream object holds the communication channel with the
|
|
* child's process standard output. It is stored in a pointer because
|
|
* this field is only valid when the user requested to redirect this
|
|
* data stream.
|
|
*/
|
|
boost::shared_ptr<pistream> stdout_;
|
|
|
|
/**
|
|
* The standard error stream attached to the child process.
|
|
*
|
|
* This postream object holds the communication channel with the
|
|
* child's process standard error. It is stored in a pointer because
|
|
* this field is only valid when the user requested to redirect this
|
|
* data stream.
|
|
*/
|
|
boost::shared_ptr<pistream> stderr_;
|
|
|
|
#if defined(BOOST_WINDOWS_API)
|
|
/**
|
|
* Process handle owned by RAII object.
|
|
*/
|
|
boost::shared_ptr<void> process_handle_;
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Collection of child objects.
|
|
*
|
|
* This convenience type represents a collection of child objects backed
|
|
* by a vector.
|
|
*/
|
|
typedef std::vector<child> children;
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|