1 // Copyright (c) 2016 Klemens D. Morgenstern
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
7 #define BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
8 
9 #include <boost/process/detail/config.hpp>
10 #include <boost/process/detail/posix/child_handle.hpp>
11 #include <system_error>
12 #include <unistd.h>
13 
14 namespace boost { namespace process { namespace detail { namespace posix {
15 
16 struct group_handle
17 {
18     pid_t grp = -1;
19 
20     typedef pid_t handle_t;
handleboost::process::detail::posix::group_handle21     handle_t handle() const { return grp; }
22 
group_handleboost::process::detail::posix::group_handle23     explicit group_handle(handle_t h) :
24         grp(h)
25     {
26     }
27 
28      group_handle() = default;
29 
30     ~group_handle() = default;
31     group_handle(const group_handle & c) = delete;
group_handleboost::process::detail::posix::group_handle32     group_handle(group_handle && c) : grp(c.grp)
33     {
34         c.grp = -1;
35     }
36     group_handle &operator=(const group_handle & c) = delete;
operator =boost::process::detail::posix::group_handle37     group_handle &operator=(group_handle && c)
38     {
39         grp = c.grp;
40         c.grp = -1;
41         return *this;
42     }
43 
addboost::process::detail::posix::group_handle44     void add(handle_t proc)
45     {
46         if (::setpgid(proc, grp))
47             throw_last_error();
48     }
addboost::process::detail::posix::group_handle49     void add(handle_t proc, std::error_code & ec) noexcept
50     {
51         if (::setpgid(proc, grp))
52             ec = get_last_error();
53     }
54 
hasboost::process::detail::posix::group_handle55     bool has(handle_t proc)
56     {
57         return ::getpgid(proc) == grp;
58     }
hasboost::process::detail::posix::group_handle59     bool has(handle_t proc, std::error_code &) noexcept
60     {
61         return ::getpgid(proc) == grp;
62     }
63 
validboost::process::detail::posix::group_handle64     bool valid() const
65     {
66         return grp != -1;
67     }
68 };
69 
terminate(group_handle & p,std::error_code & ec)70 inline  void terminate(group_handle &p, std::error_code &ec) noexcept
71 {
72     if (::killpg(p.grp, SIGKILL) == -1)
73         ec = boost::process::detail::get_last_error();
74     else
75         ec.clear();
76 
77     p.grp = -1;
78 }
79 
terminate(group_handle & p)80 inline void terminate(group_handle &p)
81 {
82     std::error_code ec;
83     terminate(p, ec);
84     boost::process::detail::throw_error(ec, "killpg(2) failed in terminate");
85 }
86 
in_group()87 inline bool in_group()
88 {
89     return true;
90 }
91 
92 }}}}
93 
94 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */
95