123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- // Copyright (c) 2022 Klemens D. Morgenstern
- // Copyright (c) 2022 Samuel Venable
- //
- // 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_V2_IMPL_EXE_IPP
- #define BOOST_PROCESS_V2_IMPL_EXE_IPP
- #include <boost/process/v2/detail/config.hpp>
- #include <boost/process/v2/detail/last_error.hpp>
- #include <boost/process/v2/detail/throw_error.hpp>
- #include <boost/process/v2/ext/detail/proc_info.hpp>
- #include <boost/process/v2/ext/exe.hpp>
- #include <string>
- #include <vector>
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- #include <windows.h>
- #else
- #include <climits>
- #endif
- #if (defined(__APPLE__) && defined(__MACH__))
- #include <sys/proc_info.h>
- #include <libproc.h>
- #endif
- #if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun))
- #include <cstdlib>
- #endif
- #if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
- #include <sys/types.h>
- #include <sys/sysctl.h>
- #if !defined(__FreeBSD__)
- #include <alloca.h>
- #endif
- #endif
- #if defined(__OpenBSD__)
- #include <boost/process/v2/ext/cwd.hpp>
- #include <boost/process/v2/ext/cmd.hpp>
- #include <boost/process/v2/ext/env.hpp>
- #include <boost/algorithm/string.hpp>
- #include <boost/algorithm/string/split.hpp>
- #include <boost/algorithm/string/classification.hpp>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/sysctl.h>
- #include <kvm.h>
- #endif
- BOOST_PROCESS_V2_BEGIN_NAMESPACE
- namespace ext {
- #if defined(BOOST_PROCESS_V2_WINDOWS)
- filesystem::path exe(HANDLE process_handle)
- {
- boost::system::error_code ec;
- auto res = exe(process_handle, ec);
- if (ec)
- detail::throw_error(ec, "exe");
- return res;
- }
- filesystem::path exe(HANDLE proc, boost::system::error_code & ec)
- {
- wchar_t buffer[MAX_PATH];
- // On input, specifies the size of the lpExeName buffer, in characters.
- DWORD size = MAX_PATH;
- if (QueryFullProcessImageNameW(proc, 0, buffer, &size))
- {
- return filesystem::canonical(buffer, ec);
- }
- else
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- return "";
- }
- filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
- {
- if (pid == GetCurrentProcessId())
- {
- wchar_t buffer[MAX_PATH];
- if (GetModuleFileNameW(nullptr, buffer, sizeof(buffer)))
- {
- return filesystem::canonical(buffer, ec);
- }
- }
- else
- {
- struct del
- {
- void operator()(HANDLE h)
- {
- ::CloseHandle(h);
- };
- };
- std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)};
- if (proc == nullptr)
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- else
- return exe(proc.get(), ec);
- }
- return "";
- }
- #elif (defined(__APPLE__) && defined(__MACH__))
- filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
- {
- char buffer[PROC_PIDPATHINFO_MAXSIZE];
- if (proc_pidpath(pid, buffer, sizeof(buffer)) > 0)
- {
- return filesystem::canonical(buffer, ec);
- }
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- return "";
- }
- #elif (defined(__linux__) || defined(__ANDROID__) || defined(__sun))
- filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
- {
- #if (defined(__linux__) || defined(__ANDROID__))
- return filesystem::canonical(
- filesystem::path("/proc") / std::to_string(pid) / "exe", ec
- );
- #elif defined(__sun)
- return fileystem::canonical(
- filesystem::path("/proc") / std::to_string(pid) / "path/a.out", ec
- );
- #endif
- }
- #elif (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
- filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
- {
- #if (defined(__FreeBSD__) || defined(__DragonFly__))
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid};
- #elif defined(__NetBSD__)
- int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME};
- #endif
- std::size_t len = 0;
- if (sysctl(mib, 4, nullptr, &len, nullptr, 0) == 0)
- {
- std::string strbuff;
- strbuff.resize(len);
- if (sysctl(mib, 4, &strbuff[0], &len, nullptr, 0) == 0)
- {
- strbuff.resize(len - 1);
- return filesystem::canonical(strbuff, ec);
- }
- }
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- return "";
- }
- #elif defined(__OpenBSD__)
- filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
- {
- BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, boost::system::system_category())
- return "";
- }
- #else
- #error "Platform not supported"
- #endif
- filesystem::path exe(boost::process::v2::pid_type pid)
- {
- boost::system::error_code ec;
- auto res = exe(pid, ec);
- if (ec)
- detail::throw_error(ec, "exe");
- return res;
- }
- } // namespace ext
- BOOST_PROCESS_V2_END_NAMESPACE
- #endif // BOOST_PROCESS_V2_IMPL_EXE_IPP
|