// Copyright (c) 2006, 2007 Julio M. Merino Vidal // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling // Copyright (c) 2009 Boris Schaeling // Copyright (c) 2010 Felipe Tanus, Boris Schaeling // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling // Copyright (c) 2016 Klemens D. Morgenstern // // 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 * * Defines a child process class. */ #ifndef BOOST_PROCESS_CHILD_HPP #define BOOST_PROCESS_CHILD_HPP #include #include #include #if defined(BOOST_POSIX_API) #include #endif namespace boost { ///The main namespace of boost.process. namespace process { template child::child(Args&&...args) : child(::boost::process::detail::execute_impl(std::forward(args)...)) {} ///Typedef for the type of an pid_t typedef ::boost::process::detail::api::pid_t pid_t; #if defined(BOOST_PROCESS_DOXYGEN) /** The main class to hold a child process. It is simliar to [std::thread](http://en.cppreference.com/w/cpp/thread/thread), * in that it has a join and detach function. * * @attention The destructor will call terminate on the process if not joined or detached without any warning. * */ class child { /** Type definition for the native process handle. */ typedef platform_specific native_handle_t; /** Construct the child from a pid. * * @attention There is no guarantee that this will work. The process need the right access rights, which are very platform specific. */ explicit child(pid_t & pid) : _child_handle(pid) {}; /** Move-Constructor.*/ child(child && lhs); /** Construct a child from a property list and launch it * The standard version is to create a subprocess, which will spawn the process. */ template explicit child(Args&&...args); /** Construct an empty child. */ child() = default; /** Move assign. */ child& operator=(child && lhs); /** Detach the child, i.e. let it run after this handle dies. */ void detach(); /** Join the child. This just calls wait, but that way the naming is similar to std::thread */ void join(); /** Check if the child is joinable. */ bool joinable(); /** Destructor. * @attention Will call terminate (without warning) when the child was neither joined nor detached. */ ~child(); /** Get the native handle for the child process. */ native_handle_t native_handle() const; /** Get the exit_code. The return value is without any meaning if the child wasn't waited for or if it was terminated. */ int exit_code() const; /** Get the Process Identifier. */ pid_t id() const; /** Get the native, uninterpreted exit code. The return value is without any meaning if the child wasn't waited * for or if it was terminated. */ int native_exit_code() const; /** Check if the child process is running. */ bool running(); /** \overload void running() */ bool running(std::error_code & ec) noexcept; /** Wait for the child process to exit. */ void wait(); /** \overload void wait() */ void wait(std::error_code & ec) noexcept; /** Wait for the child process to exit for a period of time. * \return True if child exited while waiting. */ template< class Rep, class Period > bool wait_for (const std::chrono::duration& rel_time); /** \overload bool wait_for(const std::chrono::duration& rel_time) */ bool wait_for (const std::chrono::duration& rel_time, std::error_code & ec) noexcept; /** Wait for the child process to exit until a point in time. * \return True if child exited while waiting.*/ template< class Clock, class Duration > bool wait_until(const std::chrono::time_point& timeout_time ); /** \overload bool wait_until(const std::chrono::time_point& timeout_time )*/ bool wait_until(const std::chrono::time_point& timeout_time, std::error_code & ec) noexcept; /** Check if this handle holds a child process. * @note That does not mean, that the process is still running. It only means, that the handle does or did exist. */ bool valid() const; /** Same as valid, for convenience. */ explicit operator bool() const; /** Check if the the chlid process is in any process group. */ bool in_group() const; /** \overload bool in_group() const */ bool in_group(std::error_code & ec) const noexcept; /** Terminate the child process. * * This function will cause the child process to unconditionally and immediately exit. * It is implement with [SIGKILL](http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html) on posix * and [TerminateProcess](https://technet.microsoft.com/en-us/library/ms686714.aspx) on windows. * */ void terminate(); /** \overload void terminate() */ void terminate(std::error_code & ec) noexcept; }; #endif }} #endif