Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:10

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 // Copyright (c) 2022 Samuel Venable
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // On input, specifies the size of the lpExeName buffer, in characters.
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 } // namespace ext
0189 
0190 BOOST_PROCESS_V2_END_NAMESPACE
0191 
0192 #endif // BOOST_PROCESS_V2_IMPL_EXE_IPP
0193