/usr/include/boost/process/detail/windows
NameSizeModeActions
asio_fwd.hpp13540644editdlrm
async_handler.hpp11950644editdlrm
async_in.hpp35570644editdlrm
async_out.hpp60790644editdlrm
async_pipe.hpp176110644editdlrm
basic_cmd.hpp50720644editdlrm
basic_pipe.hpp84510644editdlrm
child_handle.hpp31850644editdlrm
close_in.hpp10400644editdlrm
close_out.hpp17430644editdlrm
cmd.hpp9930644editdlrm
compare_handles.hpp14880644editdlrm
environment.hpp109760644editdlrm
env_init.hpp16150644editdlrm
executor.hpp80450644editdlrm
file_descriptor.hpp37470644editdlrm
file_in.hpp17350644editdlrm
file_out.hpp26910644editdlrm
group_handle.hpp65270644editdlrm
group_ref.hpp15720644editdlrm
handler.hpp5660644editdlrm
handles.hpp57460644editdlrm
handle_workaround.hpp89240644editdlrm
io_context_ref.hpp50430644editdlrm
is_running.hpp14110644editdlrm
job_workaround.hpp97210644editdlrm
locale.hpp31540644editdlrm
null_in.hpp15590644editdlrm
null_out.hpp25760644editdlrm
on_exit.hpp12020644editdlrm
pipe_in.hpp25710644editdlrm
pipe_out.hpp35350644editdlrm
search_path.hpp28080644editdlrm
shell_path.hpp15680644editdlrm
show_window.hpp13080644editdlrm
start_dir.hpp10260644editdlrm
terminate.hpp13290644editdlrm
wait_for_exit.hpp40480644editdlrm
wait_group.hpp43370644editdlrm
Edit: /usr/include/boost/process/detail/windows/handles.hpp (5746B)
// Copyright (c) 2019 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) #ifndef BOOST_PROCESS_DETAIL_WINDOWS_HANDLES_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_HANDLES_HPP_ #include #include #include #include #include namespace boost { namespace process { namespace detail { template void foreach_used_handle(Executor &exec, Function &&func); namespace windows { using native_handle_type = ::boost::winapi::HANDLE_ ; inline std::vector get_handles(std::error_code & ec) { auto pid = ::boost::winapi::GetCurrentProcessId(); std::vector buffer(2048); constexpr static auto STATUS_INFO_LENGTH_MISMATCH_ = static_cast<::boost::winapi::NTSTATUS_>(0xC0000004l); auto info_pointer = reinterpret_cast(buffer.data()); ::boost::winapi::NTSTATUS_ nt_status = STATUS_INFO_LENGTH_MISMATCH_; for (; nt_status == STATUS_INFO_LENGTH_MISMATCH_; nt_status = workaround::nt_system_query_information( workaround::SystemHandleInformation_, info_pointer, static_cast<::boost::winapi::ULONG_>(buffer.size()), nullptr)) { buffer.resize(buffer.size() * 2); info_pointer = reinterpret_cast(buffer.data()); } if (nt_status < 0 || nt_status > 0x7FFFFFFF) { ec = ::boost::process::detail::get_last_error(); return {}; } else ec.clear(); std::vector res; for (auto itr = info_pointer->Handle; itr != (info_pointer->Handle + info_pointer->Count); itr++) { if (itr->OwnerPid == pid) res.push_back(reinterpret_cast(static_cast(itr->HandleValue))); } return res; } inline std::vector get_handles() { std::error_code ec; auto res = get_handles(ec); if (ec) boost::process::detail::throw_error(ec, "NtQuerySystemInformation failed"); return res; } inline bool is_stream_handle(native_handle_type handle, std::error_code & ec) { ::boost::winapi::ULONG_ actual_size; auto nt_status = workaround::nt_query_object( handle, workaround::ObjectTypeInformation, NULL, 0, &actual_size); std::vector vec; vec.resize(actual_size); workaround::OBJECT_TYPE_INFORMATION_ * type_info_p = reinterpret_cast(vec.data()); nt_status = workaround::nt_query_object( handle, workaround::ObjectTypeInformation, type_info_p, actual_size, &actual_size); if (nt_status < 0 || nt_status > 0x7FFFFFFF) { ec = ::boost::process::detail::get_last_error(); return false; } else ec.clear(); auto &nm = type_info_p->TypeName.Buffer; return type_info_p->TypeName.Length >= 5 && nm[0] == L'F' && nm[1] == L'i' && nm[2] == L'l' && nm[3] == L'e' && nm[4] == L'\0'; } inline bool is_stream_handle(native_handle_type handle) { std::error_code ec; auto res = is_stream_handle(handle, ec); if (ec) boost::process::detail::throw_error(ec, "NtQueryObject failed"); return res; } struct limit_handles_ : handler_base_ext { mutable std::vector<::boost::winapi::HANDLE_> handles_with_inherit_flag; template void on_setup(Executor & exec) const { auto all_handles = get_handles(); foreach_used_handle(exec, [&](::boost::winapi::HANDLE_ handle) { auto itr = std::find(all_handles.begin(), all_handles .end(), handle); DWORD flags = 0u; if (itr != all_handles.end()) *itr = ::boost::winapi::INVALID_HANDLE_VALUE_; else if ((::boost::winapi::GetHandleInformation(*itr, &flags) != 0) &&((flags & ::boost::winapi::HANDLE_FLAG_INHERIT_) == 0)) //it is NOT inherited anyhow, so ignore too *itr = ::boost::winapi::INVALID_HANDLE_VALUE_; }); auto part_itr = std::partition(all_handles.begin(), all_handles.end(), [](::boost::winapi::HANDLE_ handle) {return handle != ::boost::winapi::INVALID_HANDLE_VALUE_;}); all_handles.erase(part_itr, all_handles.end()); //remove invalid handles handles_with_inherit_flag = std::move(all_handles); for (auto handle : handles_with_inherit_flag) ::boost::winapi::SetHandleInformation(handle, ::boost::winapi::HANDLE_FLAG_INHERIT_, 0); } template void on_error(Executor & exec, const std::error_code & ec) const { for (auto handle : handles_with_inherit_flag) ::boost::winapi::SetHandleInformation(handle, ::boost::winapi::HANDLE_FLAG_INHERIT_, ::boost::winapi::HANDLE_FLAG_INHERIT_); } template void on_sucess(Executor & exec) const { for (auto handle : handles_with_inherit_flag) ::boost::winapi::SetHandleInformation(handle, ::boost::winapi::HANDLE_FLAG_INHERIT_, ::boost::winapi::HANDLE_FLAG_INHERIT_); } }; }}}} #endif //PROCESS_HANDLES_HPP