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.
 
 
 
 
 

209 lines
6.0 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/context.hpp
*
* Includes the declaration of the context class and several accessory
* base classes.
*/
#ifndef BOOST_PROCESS_CONTEXT_HPP
#define BOOST_PROCESS_CONTEXT_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <boost/scoped_array.hpp>
# include <cerrno>
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/environment.hpp>
#include <boost/process/stream_behavior.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <string>
#include <vector>
namespace boost {
namespace process {
/**
* Base context class that defines the child's work directory.
*
* Base context class that defines the necessary fields to configure a
* child's work directory. This class is useless on its own because no
* function in the library will accept it as a valid Context
* implementation.
*/
template <class Path>
class basic_work_directory_context
{
public:
/**
* Constructs a new work directory context.
*
* Constructs a new work directory context making the work directory
* described by the new object point to the caller's current working
* directory.
*/
basic_work_directory_context()
{
#if defined(BOOST_POSIX_API)
errno = 0;
long size = ::pathconf(".", _PC_PATH_MAX);
if (size == -1 && errno)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: pathconf(2) failed"));
else if (size == -1)
size = BOOST_PROCESS_POSIX_PATH_MAX;
boost::scoped_array<char> cwd(new char[size]);
if (!::getcwd(cwd.get(), size))
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: getcwd(2) failed"));
work_directory = cwd.get();
#elif defined(BOOST_WINDOWS_API)
char cwd[MAX_PATH];
if (!::GetCurrentDirectoryA(sizeof(cwd), cwd))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: GetCurrentDirectory failed"));
work_directory = cwd;
#endif
BOOST_ASSERT(!work_directory.empty());
}
/**
* The process' initial work directory.
*
* The work directory is the directory in which the process starts
* execution.
*/
Path work_directory;
};
/**
* Base context class that defines the child's environment.
*
* Base context class that defines the necessary fields to configure a
* child's environment variables. This class is useless on its own
* because no function in the library will accept it as a valid Context
* implementation.
*/
class environment_context
{
public:
/**
* The process' environment.
*
* Contains the list of environment variables, alongside with their
* values, that will be passed to the spawned child process.
*/
boost::process::environment environment;
};
/**
* Process startup execution context.
*
* The context class groups all the parameters needed to configure a
* process' environment during its creation.
*/
template <class Path>
class basic_context : public basic_work_directory_context<Path>, public environment_context
{
public:
/**
* Child's stdin behavior.
*/
stream_behavior stdin_behavior;
/**
* Child's stdout behavior.
*/
stream_behavior stdout_behavior;
/**
* Child's stderr behavior.
*/
stream_behavior stderr_behavior;
};
typedef basic_context<std::string> context;
/**
* Represents a child process in a pipeline.
*
* This convenience class is a triplet that holds all the data required
* to spawn a new child process in a pipeline.
*/
template <class Executable, class Arguments, class Context>
class basic_pipeline_entry
{
public:
/**
* The executable to launch.
*/
Executable executable;
/**
* The set of arguments to pass to the executable.
*/
Arguments arguments;
/**
* The child's execution context.
*/
Context context;
/**
* The type of the Executable concept used in this template
* instantiation.
*/
typedef Executable executable_type;
/**
* The type of the Arguments concept used in this template
* instantiation.
*/
typedef Arguments arguments_type;
/**
* The type of the Context concept used in this template
* instantiation.
*/
typedef Context context_type;
/**
* Constructs a new pipeline_entry object.
*
* Given the executable, set of arguments and execution triplet,
* constructs a new pipeline_entry object that holds the three
* values.
*/
basic_pipeline_entry(const Executable &exe, const Arguments &args, const Context &ctx)
: executable(exe),
arguments(args),
context(ctx)
{
}
};
/**
* Default instantiation of basic_pipeline_entry.
*/
typedef basic_pipeline_entry<std::string, std::vector<std::string>, context> pipeline_entry;
}
}
#endif