Bitcoin Core 31.99.0
P2P Digital Currency
exec.cpp
Go to the documentation of this file.
1// Copyright (c) 2025-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <util/exec.h>
6
7#include <util/fs.h>
8#ifdef WIN32
9#include <util/subprocess.h>
10#endif
11
12#include <cstdlib>
13#include <string>
14#include <system_error>
15
16#ifdef WIN32
17#include <codecvt>
18#include <locale>
19#include <process.h>
20#include <windows.h>
21#else
22#include <unistd.h>
23#endif
24
25namespace util {
26int ExecVp(const char* file, char* const argv[])
27{
28#ifndef WIN32
29 return execvp(file, argv);
30#else
31 std::vector<std::wstring> escaped_args;
32 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
33 for (char* const* arg_ptr{argv}; *arg_ptr; ++arg_ptr) {
34 subprocess::util::quote_argument(converter.from_bytes(*arg_ptr), escaped_args.emplace_back(), false);
35 }
36
37 std::vector<const wchar_t*> new_argv;
38 new_argv.reserve(escaped_args.size() + 1);
39 for (const auto& s : escaped_args) new_argv.push_back(s.c_str());
40 new_argv.push_back(nullptr);
41 return _wexecvp(converter.from_bytes(file).c_str(), new_argv.data());
42#endif
43}
44
45fs::path GetExePath(std::string_view argv0)
46{
47 // Try to figure out where executable is located. This does a simplified
48 // search that won't work perfectly on every platform and doesn't need to,
49 // as it is only currently being used in a convenience wrapper binary to try
50 // to prioritize locally built or installed executables over system
51 // executables.
52 const fs::path argv0_path{fs::PathFromString(std::string{argv0})};
53 fs::path path{argv0_path};
54 std::error_code ec;
55#ifndef WIN32
56 // If argv0 doesn't contain a path separator, it was invoked from the system
57 // PATH and can be searched for there.
58 if (!argv0_path.has_parent_path()) {
59 if (const char* path_env = std::getenv("PATH")) {
60 size_t start{0}, end{0};
61 for (std::string_view paths{path_env}; end != std::string_view::npos; start = end + 1) {
62 end = paths.find(':', start);
63 fs::path candidate = fs::path(paths.substr(start, end - start)) / argv0_path;
64 if (fs::is_regular_file(candidate, ec)) {
65 path = candidate;
66 break;
67 }
68 }
69 }
70 }
71#else
72 wchar_t module_path[MAX_PATH];
73 if (GetModuleFileNameW(nullptr, module_path, MAX_PATH) > 0) {
74 path = fs::path{module_path};
75 }
76#endif
77 return path;
78}
79
80} // namespace util
#define MAX_PATH
Definition: compat.h:81
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:185
int ExecVp(const char *file, char *const argv[])
Cross-platform wrapper for POSIX execvp function.
Definition: exec.cpp:26
fs::path GetExePath(std::string_view argv0)
Return path to current executable assuming it was invoked with argv0.
Definition: exec.cpp:45