static std::string lookup(LLCommandHandler::EUntrustedAccess value) { for (symbol_info *sii(symbols), *siend(symbols + (sizeof(symbols)/sizeof(symbols[0]))); sii != siend; ++sii) { if (sii->value == value) { return sii->name; } } return STRINGIZE("UNTRUSTED_" << value); }
inline children launch_pipeline(const Entries &entries) { BOOST_ASSERT(entries.size() >= 2); children cs; detail::file_handle fhinvalid; boost::scoped_array<detail::pipe> pipes(new detail::pipe[entries.size() - 1]); #if defined(BOOST_POSIX_API) { typename Entries::size_type i = 0; const typename Entries::value_type::context_type &ctx = entries[i].context; detail::info_map infoin, infoout; if (ctx.stdin_behavior.get_type() != stream_behavior::close) { detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false); infoin.insert(detail::info_map::value_type(STDIN_FILENO, si)); } BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); detail::stream_info si2(close_stream(), true); si2.type_ = detail::stream_info::use_handle; si2.handle_ = pipes[i].wend().release(); infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); if (ctx.stderr_behavior.get_type() != stream_behavior::close) { detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); } detail::posix_setup s; s.work_directory = ctx.work_directory; pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); detail::file_handle fhstdin; if (ctx.stdin_behavior.get_type() == stream_behavior::capture) { fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false); BOOST_ASSERT(fhstdin.valid()); } cs.push_back(child(pid, fhstdin, fhinvalid, fhinvalid)); } for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) { const typename Entries::value_type::context_type &ctx = entries[i].context; detail::info_map infoin, infoout; BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); detail::stream_info si1(close_stream(), false); si1.type_ = detail::stream_info::use_handle; si1.handle_ = pipes[i - 1].rend().release(); infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); detail::stream_info si2(close_stream(), true); si2.type_ = detail::stream_info::use_handle; si2.handle_ = pipes[i].wend().release(); infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); if (ctx.stderr_behavior.get_type() != stream_behavior::close) { detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); } detail::posix_setup s; s.work_directory = ctx.work_directory; pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); cs.push_back(child(pid, fhinvalid, fhinvalid, fhinvalid)); } { typename Entries::size_type i = entries.size() - 1; const typename Entries::value_type::context_type &ctx = entries[i].context; detail::info_map infoin, infoout; BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); detail::stream_info si1(close_stream(), false); si1.type_ = detail::stream_info::use_handle; si1.handle_ = pipes[i - 1].rend().release(); infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); if (ctx.stdout_behavior.get_type() != stream_behavior::close) { detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true); infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si)); } if (ctx.stderr_behavior.get_type() != stream_behavior::close) { detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); } detail::posix_setup s; s.work_directory = ctx.work_directory; pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); detail::file_handle fhstdout, fhstderr; if (ctx.stdout_behavior.get_type() == stream_behavior::capture) { fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true); BOOST_ASSERT(fhstdout.valid()); } if (ctx.stderr_behavior.get_type() == stream_behavior::capture) { fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true); BOOST_ASSERT(fhstderr.valid()); } cs.push_back(child(pid, fhinvalid, fhstdout, fhstderr)); } #elif defined(BOOST_WINDOWS_API) STARTUPINFOA si; detail::win32_setup s; s.startupinfo = &si; { typename Entries::size_type i = 0; const typename Entries::value_type::context_type &ctx = entries[i].context; detail::stream_info sii = detail::stream_info(ctx.stdin_behavior, false); detail::file_handle fhstdin; if (sii.type_ == detail::stream_info::use_pipe) fhstdin = sii.pipe_->wend(); BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); detail::stream_info sio(close_stream(), true); sio.type_ = detail::stream_info::use_handle; sio.handle_ = pipes[i].wend().release(); detail::stream_info sie(ctx.stderr_behavior, true); s.work_directory = ctx.work_directory; ::ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); if (!::CloseHandle(pi.hThread)) boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); cs.push_back(child(pi.dwProcessId, fhstdin, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); } for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) { const typename Entries::value_type::context_type &ctx = entries[i].context; BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); detail::stream_info sii(close_stream(), false); sii.type_ = detail::stream_info::use_handle; sii.handle_ = pipes[i - 1].rend().release(); detail::stream_info sio(close_stream(), true); sio.type_ = detail::stream_info::use_handle; sio.handle_ = pipes[i].wend().release(); detail::stream_info sie(ctx.stderr_behavior, true); s.work_directory = ctx.work_directory; ::ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); if (!::CloseHandle(pi.hThread)) boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); cs.push_back(child(pi.dwProcessId, fhinvalid, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); } { typename Entries::size_type i = entries.size() - 1; const typename Entries::value_type::context_type &ctx = entries[i].context; BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); detail::stream_info sii(close_stream(), false); sii.type_ = detail::stream_info::use_handle; sii.handle_ = pipes[i - 1].rend().release(); detail::file_handle fhstdout, fhstderr; detail::stream_info sio(ctx.stdout_behavior, true); if (sio.type_ == detail::stream_info::use_pipe) fhstdout = sio.pipe_->rend(); detail::stream_info sie(ctx.stderr_behavior, true); if (sie.type_ == detail::stream_info::use_pipe) fhstderr = sie.pipe_->rend(); s.work_directory = ctx.work_directory; ::ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); if (!::CloseHandle(pi.hThread)) boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); cs.push_back(child(pi.dwProcessId, fhinvalid, fhstdout, fhstderr, detail::file_handle(pi.hProcess))); } #endif return cs; }