update boost
This commit is contained in:
71
linx64/include/boost/process/v2/ext/cmd.hpp
Normal file
71
linx64/include/boost/process/v2/ext/cmd.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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_CMD_HPP
|
||||
#define BOOST_PROCESS_V2_CMD_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
#include <boost/process/v2/process_handle.hpp>
|
||||
#include <boost/process/v2/pid.hpp>
|
||||
|
||||
#include <boost/process/v2/shell.hpp>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle);
|
||||
#endif
|
||||
|
||||
/// @{
|
||||
/// Get the argument vector of another process
|
||||
BOOST_PROCESS_V2_DECL shell cmd(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL shell cmd(pid_type pid);
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle);
|
||||
#endif
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cmd(handle.native_handle(), ec);
|
||||
#else
|
||||
return cmd(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cmd(handle.native_handle());
|
||||
#else
|
||||
return cmd(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||
|
||||
#include <boost/process/v2/ext/impl/cmd.ipp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_PROCESS_V2_CMD_HPP
|
||||
58
linx64/include/boost/process/v2/ext/cwd.hpp
Normal file
58
linx64/include/boost/process/v2/ext/cwd.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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_CWD_HPP
|
||||
#define BOOST_PROCESS_V2_CWD_HPP
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
|
||||
#include <boost/process/v2/pid.hpp>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(HANDLE handle);
|
||||
#endif
|
||||
|
||||
/// @{
|
||||
/// Obtain the current path of another process
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid);
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cwd(handle.native_handle(), ec);
|
||||
#else
|
||||
return cwd(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cwd(handle.native_handle());
|
||||
#else
|
||||
return cwd(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||
#include <boost/process/v2/ext/impl/cwd.ipp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_PROCESS_V2_CWD_HPP
|
||||
127
linx64/include/boost/process/v2/ext/detail/impl/proc_info.ipp
Normal file
127
linx64/include/boost/process/v2/ext/detail/impl/proc_info.ipp
Normal file
@@ -0,0 +1,127 @@
|
||||
// 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_DETAIL_PROC_INFO_IPP
|
||||
#define BOOST_PROCESS_V2_IMPL_DETAIL_PROC_INFO_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 <string>
|
||||
|
||||
#if (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/proc_info.h>
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace ext
|
||||
{
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
// type of process memory to read?
|
||||
enum MEMTYP {MEMCMD, MEMCWD};
|
||||
std::wstring cwd_cmd_from_proc(HANDLE proc, int type, boost::system::error_code & ec)
|
||||
{
|
||||
std::wstring buffer;
|
||||
PEB peb;
|
||||
SIZE_T nRead = 0;
|
||||
ULONG len = 0;
|
||||
PROCESS_BASIC_INFORMATION pbi;
|
||||
RTL_USER_PROCESS_PARAMETERS_EXTENDED upp;
|
||||
|
||||
NTSTATUS status = 0;
|
||||
PVOID buf = nullptr;
|
||||
status = NtQueryInformationProcess(proc, ProcessBasicInformation, &pbi, sizeof(pbi), &len);
|
||||
ULONG error = RtlNtStatusToDosError(status);
|
||||
|
||||
if (error)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_EC(ec, error, boost::system::system_category())
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (type == MEMCWD)
|
||||
{
|
||||
buf = upp.CurrentDirectory.DosPath.Buffer;
|
||||
len = upp.CurrentDirectory.DosPath.Length;
|
||||
}
|
||||
else if (type == MEMCMD)
|
||||
{
|
||||
buf = upp.CommandLine.Buffer;
|
||||
len = upp.CommandLine.Length;
|
||||
}
|
||||
|
||||
buffer.resize(len / 2 + 1);
|
||||
|
||||
if (!ReadProcessMemory(proc, buf, &buffer[0], len, &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
buffer.pop_back();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// with debug_privilege enabled allows reading info from more processes
|
||||
// this includes stuff such as exe path, cwd path, cmdline, and environ
|
||||
HANDLE open_process_with_debug_privilege(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
HANDLE proc = nullptr;
|
||||
HANDLE hToken = nullptr;
|
||||
LUID luid;
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
||||
{
|
||||
if (LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, &luid))
|
||||
{
|
||||
tkp.PrivilegeCount = 1;
|
||||
tkp.Privileges[0].Luid = luid;
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if (AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), nullptr, nullptr))
|
||||
{
|
||||
proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
}
|
||||
}
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
if (!proc)
|
||||
proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
if (!proc)
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return proc;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ext
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif // BOOST_PROCESS_V2_IMPL_DETAIL_PROC_INFO_IPP
|
||||
|
||||
125
linx64/include/boost/process/v2/ext/detail/proc_info.hpp
Normal file
125
linx64/include/boost/process/v2/ext/detail/proc_info.hpp
Normal file
@@ -0,0 +1,125 @@
|
||||
// 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_DETAIL_PROC_INFO_HPP
|
||||
#define BOOST_PROCESS_V2_DETAIL_PROC_INFO_HPP
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
#include <boost/process/v2/pid.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
extern "C" ULONG NTAPI RtlNtStatusToDosError(NTSTATUS Status);
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace ext
|
||||
{
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
#if !defined(_MSC_VER)
|
||||
#pragma pack(push, 8)
|
||||
#else
|
||||
#include <pshpack8.h>
|
||||
#endif
|
||||
|
||||
/* CURDIR struct from:
|
||||
https://github.com/processhacker/phnt/
|
||||
CC BY 4.0 licence */
|
||||
|
||||
typedef struct {
|
||||
UNICODE_STRING DosPath;
|
||||
HANDLE Handle;
|
||||
} CURDIR;
|
||||
|
||||
/* RTL_DRIVE_LETTER_CURDIR struct from:
|
||||
https://github.com/processhacker/phnt/
|
||||
CC BY 4.0 licence */
|
||||
|
||||
typedef struct {
|
||||
USHORT Flags;
|
||||
USHORT Length;
|
||||
ULONG TimeStamp;
|
||||
STRING DosPath;
|
||||
} RTL_DRIVE_LETTER_CURDIR;
|
||||
|
||||
/* RTL_USER_PROCESS_PARAMETERS struct from:
|
||||
https://github.com/processhacker/phnt/
|
||||
CC BY 4.0 licence */
|
||||
|
||||
typedef struct {
|
||||
ULONG MaximumLength;
|
||||
ULONG Length;
|
||||
ULONG Flags;
|
||||
ULONG DebugFlags;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG ConsoleFlags;
|
||||
HANDLE StandardInput;
|
||||
HANDLE StandardOutput;
|
||||
HANDLE StandardError;
|
||||
CURDIR CurrentDirectory;
|
||||
UNICODE_STRING DllPath;
|
||||
UNICODE_STRING ImagePathName;
|
||||
UNICODE_STRING CommandLine;
|
||||
PVOID Environment;
|
||||
ULONG StartingX;
|
||||
ULONG StartingY;
|
||||
ULONG CountX;
|
||||
ULONG CountY;
|
||||
ULONG CountCharsX;
|
||||
ULONG CountCharsY;
|
||||
ULONG FillAttribute;
|
||||
ULONG WindowFlags;
|
||||
ULONG ShowWindowFlags;
|
||||
UNICODE_STRING WindowTitle;
|
||||
UNICODE_STRING DesktopInfo;
|
||||
UNICODE_STRING ShellInfo;
|
||||
UNICODE_STRING RuntimeData;
|
||||
RTL_DRIVE_LETTER_CURDIR CurrentDirectories[32];
|
||||
ULONG_PTR EnvironmentSize;
|
||||
ULONG_PTR EnvironmentVersion;
|
||||
PVOID PackageDependencyData;
|
||||
ULONG ProcessGroupId;
|
||||
ULONG LoaderThreads;
|
||||
UNICODE_STRING RedirectionDllName;
|
||||
UNICODE_STRING HeapPartitionName;
|
||||
ULONG_PTR DefaultThreadpoolCpuSetMasks;
|
||||
ULONG DefaultThreadpoolCpuSetMaskCount;
|
||||
} RTL_USER_PROCESS_PARAMETERS_EXTENDED;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#pragma pack(pop)
|
||||
#else
|
||||
#include <poppack.h>
|
||||
#endif
|
||||
BOOST_PROCESS_V2_DECL std::wstring cwd_cmd_from_proc(HANDLE proc, int type, boost::system::error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL HANDLE open_process_with_debug_privilege(boost::process::v2::pid_type pid, boost::system::error_code & ec);
|
||||
#endif
|
||||
|
||||
} // namespace ext
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||
|
||||
#include <boost/process/v2/ext/detail/impl/proc_info.ipp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_PROCESS_V2_DETAIL_PROC_INFO_HPP
|
||||
|
||||
155
linx64/include/boost/process/v2/ext/env.hpp
Normal file
155
linx64/include/boost/process/v2/ext/env.hpp
Normal file
@@ -0,0 +1,155 @@
|
||||
// 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_ENV_HPP
|
||||
#define BOOST_PROCESS_V2_ENV_HPP
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
#include <boost/process/v2/process_handle.hpp>
|
||||
#include <boost/process/v2/pid.hpp>
|
||||
|
||||
#include <boost/process/v2/environment.hpp>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace ext
|
||||
{
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
using native_env_handle_type = wchar_t *;
|
||||
using native_env_iterator = wchar_t *;
|
||||
#elif defined(__FreeBSD__)
|
||||
using native_env_handle_type = char **;
|
||||
using native_env_iterator = char **;
|
||||
#else
|
||||
using native_env_handle_type = char *;
|
||||
using native_env_iterator = char *;
|
||||
#endif
|
||||
|
||||
struct native_env_handle_deleter
|
||||
{
|
||||
BOOST_PROCESS_V2_DECL void operator()(native_env_handle_type) const;
|
||||
};
|
||||
|
||||
BOOST_PROCESS_V2_DECL native_env_iterator next(native_env_iterator nh);
|
||||
BOOST_PROCESS_V2_DECL native_env_iterator find_end(native_env_iterator nh);
|
||||
BOOST_PROCESS_V2_DECL const environment::char_type * dereference(native_env_iterator iterator);
|
||||
|
||||
} // namespace ext
|
||||
} // namespace detail
|
||||
|
||||
namespace ext {
|
||||
|
||||
/// The view of an environment
|
||||
struct env_view
|
||||
{
|
||||
using native_handle_type = detail::ext::native_env_handle_type;
|
||||
using value_type = environment::key_value_pair_view;
|
||||
|
||||
env_view() = default;
|
||||
env_view(env_view && nt) = default;
|
||||
|
||||
native_handle_type native_handle() { return handle_.get(); }
|
||||
|
||||
|
||||
struct iterator
|
||||
{
|
||||
using value_type = environment::key_value_pair_view;
|
||||
using difference_type = int;
|
||||
using reference = environment::key_value_pair_view;
|
||||
using pointer = environment::key_value_pair_view;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
iterator() = default;
|
||||
iterator(const iterator & ) = default;
|
||||
iterator(const detail::ext::native_env_iterator &native_handle) : iterator_(native_handle) {}
|
||||
|
||||
iterator & operator++()
|
||||
{
|
||||
iterator_ = detail::ext::next(iterator_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int)
|
||||
{
|
||||
auto last = *this;
|
||||
iterator_ = detail::ext::next(iterator_);
|
||||
return last;
|
||||
}
|
||||
environment::key_value_pair_view operator*() const
|
||||
{
|
||||
return detail::ext::dereference(iterator_);
|
||||
}
|
||||
|
||||
friend bool operator==(const iterator & l, const iterator & r) {return l.iterator_ == r.iterator_;}
|
||||
friend bool operator!=(const iterator & l, const iterator & r) {return l.iterator_ != r.iterator_;}
|
||||
|
||||
private:
|
||||
detail::ext::native_env_iterator iterator_;
|
||||
};
|
||||
|
||||
iterator begin() const {return iterator(handle_.get());}
|
||||
iterator end() const {return iterator(detail::ext::find_end(handle_.get()));}
|
||||
|
||||
private:
|
||||
friend BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
friend BOOST_PROCESS_V2_DECL env_view env(HANDLE handle, error_code & ec);
|
||||
#endif
|
||||
|
||||
std::unique_ptr<typename remove_pointer<detail::ext::native_env_handle_type>::type,
|
||||
detail::ext::native_env_handle_deleter> handle_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL env_view env(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL env_view env(HANDLE handle);
|
||||
#endif
|
||||
|
||||
/// @{
|
||||
/// Get the environment of another process.
|
||||
BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL env_view env(pid_type pid);
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return env(handle.native_handle(), ec);
|
||||
#else
|
||||
return env(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return env(handle.native_handle());
|
||||
#else
|
||||
return env(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||
|
||||
#include <boost/process/v2/ext/impl/env.ipp>
|
||||
|
||||
#endif
|
||||
#endif // BOOST_PROCESS_V2_ENV_HPP
|
||||
62
linx64/include/boost/process/v2/ext/exe.hpp
Normal file
62
linx64/include/boost/process/v2/ext/exe.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// 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_EXE_HPP
|
||||
#define BOOST_PROCESS_V2_EXE_HPP
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
|
||||
#include <boost/process/v2/process_handle.hpp>
|
||||
#include <boost/process/v2/pid.hpp>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle);
|
||||
#endif
|
||||
|
||||
/// @{
|
||||
/// Return the executable of another process by pid or handle.
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(pid_type pid);
|
||||
|
||||
|
||||
|
||||
template<typename Executor>
|
||||
filesystem::path exe(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return exe(handle.native_handle(), ec);
|
||||
#else
|
||||
return exe(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
filesystem::path exe(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return exe(handle.native_handle());
|
||||
#else
|
||||
return exe(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||
#include <boost/process/v2/ext/impl/exe.ipp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_PROCESS_V2_EXE_HPP
|
||||
|
||||
460
linx64/include/boost/process/v2/ext/impl/cmd.ipp
Normal file
460
linx64/include/boost/process/v2/ext/impl/cmd.ipp
Normal file
@@ -0,0 +1,460 @@
|
||||
// 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_CMD_IPP
|
||||
#define BOOST_PROCESS_V2_IMPL_CMD_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/cmd.hpp>
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#else
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__ANDROID__))
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/user.h>
|
||||
#include <libprocstat.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__DragonFly__) || defined(__OpenBSD__))
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <kvm.h>
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#include <sys/types.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/proc.h>
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
struct make_cmd_shell_
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
static shell make(std::wstring data)
|
||||
{
|
||||
shell res;
|
||||
res.input_ = res.buffer_ = std::move(data);
|
||||
res.parse_();
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
static shell make(std::string data,
|
||||
int argc, char ** argv,
|
||||
void(*free_func)(int, char**))
|
||||
{
|
||||
shell res;
|
||||
res.argc_ = argc;
|
||||
res.input_ = res.buffer_ = std::move(data);
|
||||
res.argv_ = argv;
|
||||
res.free_argv_ = free_func;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static shell clone(char ** cmd)
|
||||
{
|
||||
shell res;
|
||||
res.argc_ = 0;
|
||||
std::size_t str_lengths = 0;
|
||||
for (auto c = cmd; *c != nullptr; c++)
|
||||
{
|
||||
res.argc_++;
|
||||
str_lengths += (std::strlen(*c) + 1);
|
||||
}
|
||||
// yes, not the greatest solution.
|
||||
res.buffer_.resize(str_lengths);
|
||||
|
||||
res.argv_ = new char*[res.argc_ + 1];
|
||||
res.free_argv_ = +[](int argc, char ** argv) {delete[] argv;};
|
||||
res.argv_[res.argc_] = nullptr;
|
||||
auto p = &*res.buffer_.begin();
|
||||
|
||||
for (int i = 0; i < res.argc_; i++)
|
||||
{
|
||||
const auto ln = std::strlen(cmd[i]);
|
||||
res.argv_[i] = std::strcpy(p, cmd[i]);
|
||||
p += (ln + 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
|
||||
shell cmd(HANDLE proc, error_code & ec)
|
||||
{
|
||||
std::wstring buffer = boost::process::v2::detail::ext::cwd_cmd_from_proc(proc, 0/*=MEMCMD*/, ec);
|
||||
|
||||
if (!ec)
|
||||
return make_cmd_shell_::make(std::move(buffer));
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
shell cmd(HANDLE proc)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = cmd(proc, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "cmd");
|
||||
return res;
|
||||
}
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
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 cmd(proc.get(), ec);
|
||||
|
||||
}
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__))
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
int mib[3] = {CTL_KERN, KERN_ARGMAX, 0};
|
||||
int argmax = 0;
|
||||
auto size = sizeof(argmax);
|
||||
if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string procargs;
|
||||
procargs.resize(argmax - 1);
|
||||
mib[1] = KERN_PROCARGS;
|
||||
mib[2] = pid;
|
||||
|
||||
size = argmax;
|
||||
|
||||
if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
int argc = *reinterpret_cast<const int*>(procargs.data());
|
||||
auto itr = procargs.begin() + sizeof(argc);
|
||||
|
||||
std::unique_ptr<char*[]> argv{new char*[argc + 1]};
|
||||
const auto end = procargs.end();
|
||||
|
||||
argv[argc] = nullptr; //args is a null-terminated list
|
||||
|
||||
for (auto n = 0u; n <= argc; n++)
|
||||
{
|
||||
auto e = std::find(itr, end, '\0');
|
||||
if (e == end && n < argc) // something off
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category())
|
||||
return {};
|
||||
}
|
||||
argv[n] = &*itr;
|
||||
itr = e + 1; // start searching start
|
||||
}
|
||||
|
||||
auto fr_func = +[](int argc, char ** argv) {delete [] argv;};
|
||||
|
||||
return make_cmd_shell_::make(std::move(procargs), argc, argv.release(), fr_func);
|
||||
}
|
||||
|
||||
#elif (defined(__linux__) || defined(__ANDROID__))
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::string procargs;
|
||||
procargs.resize(4096);
|
||||
int f = ::open(("/proc/" + std::to_string(pid) + "/cmdline").c_str(), O_RDONLY);
|
||||
|
||||
while (procargs.back() != EOF)
|
||||
{
|
||||
auto r = ::read(f, &*(procargs.end() - 4096), 4096);
|
||||
if (r < 0)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
::close(f);
|
||||
return {};
|
||||
}
|
||||
if (r < 4096) // done!
|
||||
{
|
||||
procargs.resize(procargs.size() - 4096 + r);
|
||||
break;
|
||||
}
|
||||
procargs.resize(procargs.size() + 4096);
|
||||
}
|
||||
::close(f);
|
||||
|
||||
if (procargs.back() == EOF)
|
||||
procargs.pop_back();
|
||||
|
||||
auto argc = std::count(procargs.begin(), procargs.end(), '\0');
|
||||
|
||||
auto itr = procargs.begin();
|
||||
|
||||
std::unique_ptr<char*[]> argv{new char*[argc + 1]};
|
||||
const auto end = procargs.end();
|
||||
|
||||
argv[argc] = nullptr; //args is a null-terminated list
|
||||
|
||||
|
||||
for (auto n = 0u; n <= argc; n++)
|
||||
{
|
||||
auto e = std::find(itr, end, '\0');
|
||||
if (e == end && n < argc) // something off
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category())
|
||||
return {};
|
||||
}
|
||||
argv[n] = &*itr;
|
||||
itr = e + 1; // start searching start
|
||||
}
|
||||
|
||||
auto fr_func = +[](int argc, char ** argv) {delete [] argv;};
|
||||
|
||||
return make_cmd_shell_::make(std::move(procargs), argc, argv.release(), fr_func);
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
struct cl_proc_stat
|
||||
{
|
||||
void operator()(struct procstat *proc_stat)
|
||||
{
|
||||
procstat_close(proc_stat);
|
||||
}
|
||||
};
|
||||
std::unique_ptr<struct procstat, cl_proc_stat> proc_stat{procstat_open_sysctl()};
|
||||
if (!proc_stat)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
struct proc_info_close
|
||||
{
|
||||
struct procstat * proc_stat;
|
||||
|
||||
void operator()(struct kinfo_proc * proc_info)
|
||||
{
|
||||
procstat_freeprocs(proc_stat, proc_info);
|
||||
}
|
||||
};
|
||||
|
||||
unsigned cntp;
|
||||
std::unique_ptr<struct kinfo_proc, proc_info_close> proc_info{
|
||||
procstat_getprocs(proc_stat.get(), KERN_PROC_PID, pid, &cntp),
|
||||
proc_info_close{proc_stat.get()}};
|
||||
|
||||
if (!proc_info)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
char **cmd = procstat_getargv(proc_stat.get(), proc_info.get(), 0);
|
||||
if (!cmd)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
auto res = make_cmd_shell_::clone(cmd);
|
||||
procstat_freeargv(proc_stat.get());
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif defined(__DragonFly__)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv(kd.get(), proc_info, 0);
|
||||
if (cmd)
|
||||
return make_cmd_shell_::clone(cmd);
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
|
||||
std::vector<std::string> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;}
|
||||
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv2(kd.get(), proc_info, 0);
|
||||
if (cmd)
|
||||
return make_cmd_shell_::clone(cmd);
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return vec;
|
||||
}
|
||||
|
||||
#elif defined(__OpenBSD__)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv(kd.get(), proc_info, 0);
|
||||
if (cmd)
|
||||
return make_cmd_shell_::clone(cmd);
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
kvm_close(kd);
|
||||
return {};
|
||||
}
|
||||
|
||||
#elif defined(__sun)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
char **cmd = nullptr;
|
||||
proc *proc_info = nullptr;
|
||||
user *proc_user = nullptr;
|
||||
kd = kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};}
|
||||
if ((proc_info = kvm_getproc(kd, pid)))
|
||||
{
|
||||
if ((proc_user = kvm_getu(kd, proc_info)))
|
||||
{
|
||||
if (!kvm_getcmd(kd, proc_info, proc_user, &cmd, nullptr))
|
||||
{
|
||||
int argc = 0;
|
||||
for (int i = 0; cmd[i] != nullptr; i++)
|
||||
argc ++;
|
||||
return make_cmd_shell_::make(
|
||||
{}, argc, cmd,
|
||||
+[](int, char ** argv) {::free(argv);})
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
|
||||
kvm_close(kd);
|
||||
return {};
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = cmd(pid, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "cmd");
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif // BOOST_PROCESS_V2_IMPL_CMD_IPP
|
||||
|
||||
234
linx64/include/boost/process/v2/ext/impl/cwd.ipp
Normal file
234
linx64/include/boost/process/v2/ext/impl/cwd.ipp
Normal file
@@ -0,0 +1,234 @@
|
||||
// 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_CWD_IPP
|
||||
#define BOOST_PROCESS_V2_IMPL_CWD_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/cwd.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#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__)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/user.h>
|
||||
#include <libprocstat.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__NetBSD__) || defined(__OpenBSD__))
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__)
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_PROCESS_USE_STD_FS
|
||||
namespace filesystem = std::filesystem;
|
||||
#else
|
||||
namespace filesystem = boost::filesystem;
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
|
||||
filesystem::path cwd(HANDLE proc, boost::system::error_code & ec)
|
||||
{
|
||||
auto buffer = boost::process::v2::detail::ext::cwd_cmd_from_proc(proc, 1/*=MEMCWD*/, ec);
|
||||
if (!buffer.empty())
|
||||
return filesystem::canonical(buffer, ec);
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return "";
|
||||
}
|
||||
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
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 cwd(proc.get(), ec);
|
||||
return {};
|
||||
}
|
||||
|
||||
filesystem::path cwd(HANDLE proc)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = cwd(proc, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "cwd");
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__))
|
||||
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
proc_vnodepathinfo vpi;
|
||||
if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0)
|
||||
return filesystem::canonical(vpi.pvi_cdir.vip_path, ec);
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return "";
|
||||
}
|
||||
|
||||
#elif (defined(__linux__) || defined(__ANDROID__) || defined(__sun))
|
||||
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
return filesystem::canonical(
|
||||
filesystem::path("/proc") / std::to_string(pid) / "cwd", ec);
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
// FIXME: Add error handling.
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
filesystem::path path;
|
||||
unsigned cntp = 0;
|
||||
procstat *proc_stat = procstat_open_sysctl();
|
||||
if (proc_stat) {
|
||||
kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp);
|
||||
if (proc_info) {
|
||||
filestat_list *head = procstat_getfiles(proc_stat, proc_info, 0);
|
||||
if (head) {
|
||||
filestat *fst = nullptr;
|
||||
STAILQ_FOREACH(fst, head, next) {
|
||||
if (fst->fs_uflags & PS_FST_UFLAG_CDIR)
|
||||
{
|
||||
path = filesystem::canonical(fst->fs_path, ec);
|
||||
}
|
||||
}
|
||||
procstat_freefiles(proc_stat, head);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
procstat_freeprocs(proc_stat, proc_info);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
procstat_close(proc_stat);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return path;
|
||||
}
|
||||
|
||||
#elif defined(__DragonFly__)
|
||||
|
||||
// FIXME: Add error handling.
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
filesystem::path path;
|
||||
/* Probably the hackiest thing ever we are doing here, because the "official" API is broken OS-level. */
|
||||
FILE *fp = popen(("pos=`ans=\\`/usr/bin/fstat -w -p " + std::to_string(pid) + " | /usr/bin/sed -n 1p\\`; " +
|
||||
"/usr/bin/awk -v ans=\"$ans\" 'BEGIN{print index(ans, \"INUM\")}'`; str=`/usr/bin/fstat -w -p " +
|
||||
std::to_string(pid) + " | /usr/bin/sed -n 3p`; /usr/bin/awk -v str=\"$str\" -v pos=\"$pos\" " +
|
||||
"'BEGIN{print substr(str, 0, pos + 4)}' | /usr/bin/awk 'NF{NF--};1 {$1=$2=$3=$4=\"\"; print" +
|
||||
" substr($0, 5)'}").c_str(), "r");
|
||||
if (fp)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
if (fgets(buffer, sizeof(buffer), fp))
|
||||
{
|
||||
std::string str = buffer;
|
||||
std::size_t pos = str.find("\n", strlen(buffer) - 1);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
str.replace(pos, 1, "");
|
||||
}
|
||||
path = filesystem::canonical(str.c_str(), ec);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
pclose(fp);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return path;
|
||||
}
|
||||
|
||||
#elif (defined(__NetBSD__) || defined(__OpenBSD__))
|
||||
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::string path;
|
||||
#if defined(__NetBSD__)
|
||||
int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD};
|
||||
const std::size_t sz = 4;
|
||||
#elif defined(__OpenBSD__)
|
||||
int mib[3] = {CTL_KERN, KERN_PROC_CWD, pid};
|
||||
const std::size_t sz = 3;
|
||||
#endif
|
||||
std::size_t len = 0;
|
||||
if (sysctl(mib, sz, nullptr, &len, nullptr, 0) == 0)
|
||||
{
|
||||
std::string strbuff;
|
||||
strbuff.resize(len);
|
||||
if (sysctl(mib, 4, &strbuff[0], &len, nullptr, 0) == 0)
|
||||
{
|
||||
filesystem::canonical(strbuff, ec);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = cwd(pid, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "cwd");
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif // BOOST_PROCESS_V2_IMPL_CWD_IPP
|
||||
|
||||
389
linx64/include/boost/process/v2/ext/impl/env.ipp
Normal file
389
linx64/include/boost/process/v2/ext/impl/env.ipp
Normal file
@@ -0,0 +1,389 @@
|
||||
// Copyright (c) 2022 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_V2_EXT_IMPL_ENV_IPP
|
||||
#define BOOST_PROCESS_V2_EXT_IMPL_ENV_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/env.hpp>
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
#include <shellapi.h>
|
||||
#else
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__ANDROID__))
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
namespace ext {
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
native_env_iterator next(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != L'\0')
|
||||
nh ++;
|
||||
return ++nh ;
|
||||
}
|
||||
native_env_iterator find_end(native_env_iterator nh)
|
||||
{
|
||||
while (*nh - 1 != L'\0' && *nh != L'\0')
|
||||
nh ++;
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return iterator;
|
||||
}
|
||||
|
||||
#elif (defined(__linux__) || defined(__ANDROID__))
|
||||
//linux stores this as a blob with an EOF at the end
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
native_env_iterator next(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != '\0')
|
||||
nh ++;
|
||||
return ++nh ;
|
||||
}
|
||||
native_env_iterator find_end(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != EOF)
|
||||
nh ++;
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return iterator;
|
||||
}
|
||||
|
||||
#elif (defined(__APPLE___) || defined(__MACH__))
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
native_env_iterator next(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != '\0')
|
||||
nh ++;
|
||||
return ++nh ;
|
||||
}
|
||||
native_env_iterator find_end(native_env_iterator nh)
|
||||
{
|
||||
while (*nh - 1 != '\0' && *nh != '\0')
|
||||
nh ++;
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return iterator;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
native_env_iterator next(native_env_iterator nh)
|
||||
{
|
||||
return ++nh ;
|
||||
}
|
||||
native_env_iterator find_end(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != nullptr)
|
||||
nh++;
|
||||
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return *iterator;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace ext
|
||||
{
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
|
||||
env_view env(HANDLE proc, boost::system::error_code & ec)
|
||||
{
|
||||
wchar_t *buffer = nullptr;
|
||||
PEB peb;
|
||||
SIZE_T nRead = 0;
|
||||
ULONG len = 0;
|
||||
PROCESS_BASIC_INFORMATION pbi;
|
||||
detail::ext::RTL_USER_PROCESS_PARAMETERS_EXTENDED upp;
|
||||
|
||||
NTSTATUS status = 0;
|
||||
PVOID buf = nullptr;
|
||||
status = NtQueryInformationProcess(proc, ProcessBasicInformation, &pbi, sizeof(pbi), &len);
|
||||
ULONG error = RtlNtStatusToDosError(status);
|
||||
|
||||
if (error)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_EC(ec, error, boost::system::system_category())
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
env_view ev;
|
||||
buf = upp.Environment;
|
||||
len = (ULONG)upp.EnvironmentSize;
|
||||
ev.handle_.reset(new wchar_t[len / 2 + 1]());
|
||||
|
||||
if (!ReadProcessMemory(proc, buf, ev.handle_.get(), len, &nRead))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
ev.handle_.get()[len / 2] = L'\0';
|
||||
return ev;
|
||||
}
|
||||
|
||||
env_view env(HANDLE handle)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = env(handle, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "env");
|
||||
return res;
|
||||
}
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
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 env(proc.get(), ec);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#elif (defined(__APPLE___) || defined(__MACH__))
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
int mib[3] = {CTL_KERN, KERN_ARGMAX, 0};
|
||||
int argmax = 0;
|
||||
auto size = sizeof(argmax);
|
||||
if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string procargs;
|
||||
procargs.resize(argmax - 1);
|
||||
mib[1] = KERN_PROCARGS2;
|
||||
mib[2] = pid;
|
||||
|
||||
size = argmax;
|
||||
|
||||
if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return {};
|
||||
}
|
||||
std::uint32_t nargs;
|
||||
memcpy(&nargs, &*procargs.begin(), sizeof(nargs));
|
||||
char *cp = &*procargs.begin() + sizeof(nargs);
|
||||
|
||||
for (; cp < &*procargs.end(); cp++)
|
||||
if (*cp == '\0')
|
||||
break;
|
||||
|
||||
|
||||
if (cp == &procargs[size])
|
||||
return {};
|
||||
|
||||
|
||||
for (; cp < &*procargs.end(); cp++)
|
||||
if (*cp != '\0') break;
|
||||
|
||||
|
||||
if (cp == &*procargs.end())
|
||||
return {};
|
||||
|
||||
|
||||
int i = 0;
|
||||
char *sp = cp;
|
||||
std::vector<char> vec;
|
||||
|
||||
while ((*sp != '\0' || i < nargs) && sp < &*procargs.end()) {
|
||||
if (i >= nargs)
|
||||
vec.push_back(*sp);
|
||||
|
||||
sp += 1;
|
||||
}
|
||||
|
||||
env_view ev;
|
||||
ev.handle_.reset(new char[vec.size()]());
|
||||
std::copy(vec.begin(), vec.end(), ev.handle_.get());
|
||||
return ev;
|
||||
}
|
||||
|
||||
#elif (defined(__linux__) || defined(__ANDROID__))
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::size_t size = 0;
|
||||
std::unique_ptr<char, detail::ext::native_env_handle_deleter> procargs{};
|
||||
|
||||
int f = ::open(("/proc/" + std::to_string(pid) + "/environ").c_str(), O_RDONLY);
|
||||
|
||||
while (!procargs || procargs.get()[size - 1] != EOF)
|
||||
{
|
||||
std::unique_ptr<char, detail::ext::native_env_handle_deleter> buf{new char[size + 4096]};
|
||||
if (size > 0)
|
||||
std::memmove(buf.get(), procargs.get(), size);
|
||||
auto r = ::read(f, buf.get() + size, 4096);
|
||||
if (r < 0)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
::close(f);
|
||||
return {};
|
||||
}
|
||||
procargs = std::move(buf);
|
||||
size += r;
|
||||
if (r < 4096) // done!
|
||||
{
|
||||
procargs.get()[size] = EOF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
::close(f);
|
||||
|
||||
env_view ev;
|
||||
ev.handle_ = std::move(procargs);
|
||||
return ev;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
env_view ev;
|
||||
|
||||
unsigned cntp = 0;
|
||||
procstat *proc_stat = procstat_open_sysctl();
|
||||
if (proc_stat != nullptr)
|
||||
{
|
||||
kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp);
|
||||
if (proc_info != nullptr)
|
||||
{
|
||||
char **env = procstat_getenvv(proc_stat, proc_info, 0);
|
||||
if (env != nullptr)
|
||||
{
|
||||
auto e = env;
|
||||
std::size_t n = 0u, len = 0u;
|
||||
while (e && *e != nullptr)
|
||||
{
|
||||
n ++;
|
||||
len += std::strlen(*e);
|
||||
e++;
|
||||
}
|
||||
std::size_t mem_needed =
|
||||
// environ - nullptr - strlen + null terminators
|
||||
(n * sizeof(char*)) + sizeof(char*) + len + n;
|
||||
|
||||
char * out = new (std::nothrow) char[mem_needed];
|
||||
if (out != nullptr)
|
||||
{
|
||||
auto eno = reinterpret_cast<char**>(out);
|
||||
auto eeo = eno;
|
||||
auto str = out + (n * sizeof(char*)) + sizeof(char*);
|
||||
e = env;
|
||||
while (*e != nullptr)
|
||||
{
|
||||
auto len = std::strlen(*e) + 1u;
|
||||
std::memcpy(str, *e, len);
|
||||
*eno = str;
|
||||
str += len;
|
||||
eno ++;
|
||||
e++;
|
||||
}
|
||||
*eno = nullptr;
|
||||
|
||||
ev.handle_.reset(eeo);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
|
||||
}
|
||||
procstat_freeprocs(proc_stat, proc_info);
|
||||
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
procstat_close(proc_stat);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
|
||||
return ev;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto res = env(pid, ec);
|
||||
if (ec)
|
||||
detail::throw_error(ec, "env");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif //BOOST_PROCESS_V2_EXT_IMPL_ENV_IPP
|
||||
193
linx64/include/boost/process/v2/ext/impl/exe.ipp
Normal file
193
linx64/include/boost/process/v2/ext/impl/exe.ipp
Normal file
@@ -0,0 +1,193 @@
|
||||
// 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"
|
||||
);
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user