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