File indexing completed on 2025-01-18 09:50:10
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PROCESS_V2_IMPL_EXE_IPP
0007 #define BOOST_PROCESS_V2_IMPL_EXE_IPP
0008
0009 #include <boost/process/v2/detail/config.hpp>
0010 #include <boost/process/v2/detail/last_error.hpp>
0011 #include <boost/process/v2/detail/throw_error.hpp>
0012 #include <boost/process/v2/ext/detail/proc_info.hpp>
0013 #include <boost/process/v2/ext/exe.hpp>
0014
0015 #include <string>
0016 #include <vector>
0017
0018 #if defined(BOOST_PROCESS_V2_WINDOWS)
0019 #include <windows.h>
0020 #else
0021 #include <climits>
0022 #endif
0023
0024 #if (defined(__APPLE__) && defined(__MACH__))
0025 #include <sys/proc_info.h>
0026 #include <libproc.h>
0027 #endif
0028
0029 #if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun))
0030 #include <cstdlib>
0031 #endif
0032
0033 #if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
0034 #include <sys/types.h>
0035 #include <sys/sysctl.h>
0036 #if !defined(__FreeBSD__)
0037 #include <alloca.h>
0038 #endif
0039 #endif
0040
0041 #if defined(__OpenBSD__)
0042 #include <boost/process/v2/ext/cwd.hpp>
0043 #include <boost/process/v2/ext/cmd.hpp>
0044 #include <boost/process/v2/ext/env.hpp>
0045 #include <boost/algorithm/string.hpp>
0046 #include <boost/algorithm/string/split.hpp>
0047 #include <boost/algorithm/string/classification.hpp>
0048 #include <sys/types.h>
0049 #include <sys/param.h>
0050 #include <sys/sysctl.h>
0051 #include <kvm.h>
0052 #endif
0053
0054 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0055
0056 namespace ext {
0057
0058 #if defined(BOOST_PROCESS_V2_WINDOWS)
0059
0060 filesystem::path exe(HANDLE process_handle)
0061 {
0062 boost::system::error_code ec;
0063 auto res = exe(process_handle, ec);
0064 if (ec)
0065 detail::throw_error(ec, "exe");
0066 return res;
0067 }
0068
0069
0070 filesystem::path exe(HANDLE proc, boost::system::error_code & ec)
0071 {
0072 wchar_t buffer[MAX_PATH];
0073
0074 DWORD size = MAX_PATH;
0075 if (QueryFullProcessImageNameW(proc, 0, buffer, &size))
0076 {
0077 return filesystem::canonical(buffer, ec);
0078 }
0079 else
0080 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0081
0082 return "";
0083 }
0084
0085 filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
0086 {
0087 if (pid == GetCurrentProcessId())
0088 {
0089 wchar_t buffer[MAX_PATH];
0090 if (GetModuleFileNameW(nullptr, buffer, sizeof(buffer)))
0091 {
0092 return filesystem::canonical(buffer, ec);
0093 }
0094 }
0095 else
0096 {
0097 struct del
0098 {
0099 void operator()(HANDLE h)
0100 {
0101 ::CloseHandle(h);
0102 };
0103 };
0104 std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)};
0105 if (proc == nullptr)
0106 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0107 else
0108 return exe(proc.get(), ec);
0109 }
0110 return "";
0111 }
0112
0113 #elif (defined(__APPLE__) && defined(__MACH__))
0114
0115 filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
0116 {
0117 char buffer[PROC_PIDPATHINFO_MAXSIZE];
0118 if (proc_pidpath(pid, buffer, sizeof(buffer)) > 0)
0119 {
0120 return filesystem::canonical(buffer, ec);
0121 }
0122 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0123 return "";
0124 }
0125
0126 #elif (defined(__linux__) || defined(__ANDROID__) || defined(__sun))
0127
0128 filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
0129 {
0130 #if (defined(__linux__) || defined(__ANDROID__))
0131 return filesystem::canonical(
0132 filesystem::path("/proc") / std::to_string(pid) / "exe", ec
0133 );
0134 #elif defined(__sun)
0135 return fileystem::canonical(
0136 filesystem::path("/proc") / std::to_string(pid) / "path/a.out", ec
0137 );
0138 #endif
0139 }
0140
0141 #elif (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
0142
0143 filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
0144 {
0145 #if (defined(__FreeBSD__) || defined(__DragonFly__))
0146 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid};
0147 #elif defined(__NetBSD__)
0148 int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME};
0149 #endif
0150 std::size_t len = 0;
0151 if (sysctl(mib, 4, nullptr, &len, nullptr, 0) == 0)
0152 {
0153 std::string strbuff;
0154 strbuff.resize(len);
0155 if (sysctl(mib, 4, &strbuff[0], &len, nullptr, 0) == 0)
0156 {
0157 strbuff.resize(len - 1);
0158 return filesystem::canonical(strbuff, ec);
0159 }
0160 }
0161
0162 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0163 return "";
0164 }
0165
0166 #elif defined(__OpenBSD__)
0167
0168 filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
0169 {
0170 BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, boost::system::system_category())
0171 return "";
0172 }
0173
0174 #else
0175 #error "Platform not supported"
0176 #endif
0177
0178 filesystem::path exe(boost::process::v2::pid_type pid)
0179 {
0180 boost::system::error_code ec;
0181 auto res = exe(pid, ec);
0182 if (ec)
0183 detail::throw_error(ec, "exe");
0184 return res;
0185 }
0186
0187
0188 }
0189
0190 BOOST_PROCESS_V2_END_NAMESPACE
0191
0192 #endif
0193