From 037d6ad5aa584bdd197a00944eeca4a519c15fba Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 14 Apr 2022 18:45:47 +0200 Subject: [PATCH] Replace Boost.Process for the Wine plugin host Now we use our own library for this, so we can drop the Boost.Filesystem dependency after a couple more changes. --- src/common/logging/common.h | 216 ---------------------------------- src/plugin/host-process.cpp | 136 ++++++++++++++------- src/plugin/host-process.h | 132 ++++++--------------- src/plugin/utils.cpp | 66 ++++------- src/plugin/utils.h | 10 +- src/wine-host/bridges/group.h | 1 + 6 files changed, 148 insertions(+), 413 deletions(-) diff --git a/src/common/logging/common.h b/src/common/logging/common.h index a4afe8cd..b6f37c52 100644 --- a/src/common/logging/common.h +++ b/src/common/logging/common.h @@ -27,224 +27,8 @@ #include #include -// FIXME: Remove when we get rid of the patched_async_pipe -#include -#include -#include - -// FIXME: Get rid of Boost.Process and all of the wrangling below -#include -#include -#include - #include "../utils.h" -/** - * Boost 1.72 was released with a known breaking bug caused by a missing - * typedef: https://github.com/boostorg/process/issues/116. - * - * Luckily this is easy to fix since it's not really possible to downgrade Boost - * as it would break other applications. - * - * Check if this is still needed for other distros after Arch starts packaging - * Boost 1.73. - * - * FIXME: This has been adopted to work with standalone Asio, we should replace - * this when we replace Boost.Process - */ -class patched_async_pipe { - ::asio::posix::stream_descriptor _source; - ::asio::posix::stream_descriptor _sink; - - public: - typedef int native_handle_type; - typedef ::asio::posix::stream_descriptor handle_type; - typedef typename handle_type::executor_type executor_type; - - executor_type get_executor() { return _source.get_executor(); } - - inline patched_async_pipe(asio::io_context& ios) - : patched_async_pipe(ios, ios) {} - - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - inline patched_async_pipe(asio::io_context& ios_source, - asio::io_context& ios_sink) - : _source(ios_source), _sink(ios_sink) { - int fds[2]; - if (pipe(fds) == -1) - boost::process::detail::throw_last_error("pipe(2) failed"); - - _source.assign(fds[0]); - _sink.assign(fds[1]); - }; - - inline patched_async_pipe(const patched_async_pipe& lhs); - patched_async_pipe(patched_async_pipe&& lhs) - : _source(std::move(lhs._source)), _sink(std::move(lhs._sink)) { - lhs._source = - ::asio::posix::stream_descriptor{lhs._source.get_executor()}; - lhs._sink = ::asio::posix::stream_descriptor{lhs._sink.get_executor()}; - } - - template > - explicit patched_async_pipe( - ::asio::io_context& ios_source, - ::asio::io_context& ios_sink, - const boost::process::detail::posix::basic_pipe& p) - : _source(ios_source, p.native_source()), - _sink(ios_sink, p.native_sink()) {} - - template > - explicit patched_async_pipe( - asio::io_context& ios, - const boost::process::detail::posix::basic_pipe& p) - : patched_async_pipe(ios, ios, p) {} - - template > - inline patched_async_pipe& operator=( - const boost::process::detail::posix::basic_pipe& p); - inline patched_async_pipe& operator=(const patched_async_pipe& rhs); - - inline patched_async_pipe& operator=(patched_async_pipe&& lhs); - - ~patched_async_pipe() { - std::error_code ec; - close(ec); - } - - template > - inline explicit - operator boost::process::detail::posix::basic_pipe() const; - - void cancel() { - if (_sink.is_open()) - _sink.cancel(); - if (_source.is_open()) - _source.cancel(); - } - - void close() { - if (_sink.is_open()) - _sink.close(); - if (_source.is_open()) - _source.close(); - } - void close(std::error_code& ec) { - if (_sink.is_open()) - _sink.close(ec); - if (_source.is_open()) - _source.close(ec); - } - - bool is_open() const { return _sink.is_open() || _source.is_open(); } - void async_close() { - if (_sink.is_open()) - asio::post(_sink.get_executor(), [this] { _sink.close(); }); - if (_source.is_open()) - asio::post(_source.get_executor(), [this] { _source.close(); }); - } - - template - std::size_t read_some(const MutableBufferSequence& buffers) { - return _source.read_some(buffers); - } - template - std::size_t write_some(const MutableBufferSequence& buffers) { - return _sink.write_some(buffers); - } - - template - std::size_t read_some(const MutableBufferSequence& buffers, - std::error_code& ec) noexcept { - return _source.read_some(buffers, ec); - } - template - std::size_t write_some(const MutableBufferSequence& buffers, - std::error_code& ec) noexcept { - return _sink.write_some(buffers, ec); - } - - native_handle_type native_source() const { - return const_cast(_source) - .native_handle(); - } - native_handle_type native_sink() const { - return const_cast(_sink) - .native_handle(); - } - - template - ASIO_INITFN_RESULT_TYPE(ReadHandler, void(std::error_code, std::size_t)) - async_read_some(const MutableBufferSequence& buffers, - ReadHandler&& handler) { - return _source.async_read_some(buffers, - std::forward(handler)); - } - - template - ASIO_INITFN_RESULT_TYPE(WriteHandler, void(std::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - WriteHandler&& handler) { - return _sink.async_write_some(buffers, - std::forward(handler)); - } - - const handle_type& sink() const& { return _sink; } - const handle_type& source() const& { return _source; } - - handle_type&& sink() && { return std::move(_sink); } - handle_type&& source() && { return std::move(_source); } - - handle_type source(::asio::io_context& ios) && { - ::asio::posix::stream_descriptor stolen(ios, _source.release()); - return stolen; - } - handle_type sink(::asio::io_context& ios) && { - ::asio::posix::stream_descriptor stolen(ios, _sink.release()); - return stolen; - } - - handle_type source(::asio::io_context& ios) const& { - auto source_in = const_cast<::asio::posix::stream_descriptor&>(_source) - .native_handle(); - return ::asio::posix::stream_descriptor(ios, ::dup(source_in)); - } - handle_type sink(::asio::io_context& ios) const& { - auto sink_in = const_cast<::asio::posix::stream_descriptor&>(_sink) - .native_handle(); - return ::asio::posix::stream_descriptor(ios, ::dup(sink_in)); - } -}; - -// Even more of a mess, we can't use the nice `bp::std_out = ...`/`bp::std_err = -// ...` syntax anymore. -template -struct patched_async_pipe_out - : public boost::process::detail::posix::pipe_out { - patched_async_pipe& pipe; - template - patched_async_pipe_out(AsyncPipe& p) - : boost::process::detail::posix::pipe_out(p.native_sink(), - p.native_source()), - pipe(p) {} - - template - static void close(Pipe& pipe, Executor&) { - std::error_code ec; - std::move(pipe).sink().close(ec); - } - - template - void on_error(Executor& exec, const std::error_code&) { - close(pipe, exec); - } - - template - void on_success(Executor& exec) { - close(pipe, exec); - } -}; - /** * Super basic logging facility meant for debugging malfunctioning VST * plugins. This is also used to redirect the output of the Wine process diff --git a/src/plugin/host-process.cpp b/src/plugin/host-process.cpp index e31e4d90..c3831366 100644 --- a/src/plugin/host-process.cpp +++ b/src/plugin/host-process.cpp @@ -17,24 +17,72 @@ #include "host-process.h" #include -#include -#include #include "../common/utils.h" -namespace bp = boost::process; namespace fs = ghc::filesystem; -HostProcess::HostProcess(asio::io_context& io_context, - Logger& logger, - const Configuration& config, - Sockets& sockets) - : stdout_pipe_(io_context), - stderr_pipe_(io_context), - config_(config), - sockets_(sockets), - logger_(logger) { - // See the comment above the `on_exec_setup` in `launch_host()` +HostProcess::HostProcess(asio::io_context& io_context, Sockets& sockets) + : sockets_(sockets), stdout_pipe_(io_context), stderr_pipe_(io_context) {} + +HostProcess::~HostProcess() noexcept {} + +Process::Handle HostProcess::launch_host( + const ghc::filesystem::path& host_path, + std::initializer_list args, + Logger& logger, + const Configuration& config, + const PluginInfo& plugin_info) { +#ifdef WITH_WINEDBG + // This is set up for KDE Plasma. Other desktop environments and window + // managers require some slight modifications to spawn a detached terminal + // emulator. Alternatively, you can spawn `winedbg` with the `--no-start` + // option to launch a gdb server and then connect to it from another + // terminal. + Process child("kstart5"); + child.arg("konsole").arg("--").arg("-e").arg("winedbg").arg("--gdb"); +#ifdef WINEDBG_LEGACY_ARGUMENT_QUOTING + // Note the double quoting here. Old versions of winedbg didn't + // respect `argv` and instead expected a pre-quoted Win32 command + // line as its arguments. + child.arg("\"" + host_path.string() + ".so\""), +#else + child.arg(host_path.string() + ".so"); +#endif // WINEDBG_LEGACY_ARGUMENT_QUOTING +#else + Process child(host_path); +#endif // WITH_WINEDBG + + // What's up with this indentation + for (const auto& arg : args) { + child.arg(arg); + } + + child.environment(plugin_info.create_host_env()); + Process::Handle child_handle = std::visit( + overload{ + [](Process::Handle handle) -> Process::Handle { return handle; }, + [&host_path](const Process::CommandNotFound&) -> Process::Handle { + throw std::runtime_error("Could not launch '" + + host_path.string() + + "', command not found"); + }, + [](const std::error_code& err) -> Process::Handle { + throw std::runtime_error("Error spawning Wine process: " + + err.message()); + }, + }, + // HACK: If the `disable_pipes` option is enabled, then we'll redirect + // the plugin's output to a file instead of using pipes to blend + // it in with the rest of yabridge's output. This is for some + // reason necessary for ujam's plugins and all other plugins made + // with Gorilla Engine to function. Otherwise they'll print a + // nondescriptive `JS_EXEC_FAILED` error message. + config.disable_pipes + ? child.spawn_child_redirected(*config.disable_pipes) + : child.spawn_child_piped(stdout_pipe_, stderr_pipe_)); + + // See the above comment if (config.disable_pipes) { logger.log(""); logger.log("WARNING: All Wine output will be written to"); @@ -49,9 +97,9 @@ HostProcess::HostProcess(asio::io_context& io_context, logger.async_log_pipe_lines(stderr_pipe_, stderr_buffer_, "[Wine STDERR] "); } -} -HostProcess::~HostProcess() noexcept {} + return child_handle; +} IndividualHost::IndividualHost(asio::io_context& io_context, Logger& logger, @@ -59,28 +107,32 @@ IndividualHost::IndividualHost(asio::io_context& io_context, Sockets& sockets, const PluginInfo& plugin_info, const HostRequest& host_request) - : HostProcess(io_context, logger, config, sockets), + : HostProcess(io_context, sockets), plugin_info_(plugin_info), host_path_(find_vst_host(plugin_info.native_library_path_, plugin_info.plugin_arch_, false)), - host_( - launch_host(host_path_, - plugin_type_to_string(host_request.plugin_type), + handle_(launch_host( + host_path_, + { + plugin_type_to_string(host_request.plugin_type), #if defined(WITH_WINEDBG) && defined(WINEDBG_LEGACY_ARGUMENT_QUOTING) - // Old versions of winedbg flattened all command line - // arguments to a single space separated Win32 command - // line, so we had to do our own quoting - "\"" + plugin_info.windows_plugin_path + "\"", + // Old versions of winedbg flattened all command line + // arguments to a single space separated Win32 command line, + // so we had to do our own quoting + "\"" + plugin_info.windows_plugin_path + "\"", #else - host_request.plugin_path, + host_request.plugin_path, #endif - host_request.endpoint_base_dir, - // We pass this process' process ID as an argument so we - // can run a watchdog on the Wine plugin host process that - // shuts down the sockets after this process shuts down - std::to_string(getpid()), - bp::env = plugin_info.create_host_env())) { + host_request.endpoint_base_dir, + // We pass this process' process ID as an argument so we can + // run a watchdog on the Wine plugin host process that shuts + // down the sockets after this process shuts down + std::to_string(getpid()) + }, + logger, + config, + plugin_info)) { #ifdef WITH_WINEDBG if (plugin_info.windows_plugin_path_.string().find('"') != std::string::npos) { @@ -96,9 +148,7 @@ fs::path IndividualHost::path() { } bool IndividualHost::running() { - // NOTE: `boost::process::child::running()` still considers zombies as - // running, so it's useless for our purposes. - return pid_running(host_.id()); + return handle_.running(); } void IndividualHost::terminate() { @@ -109,10 +159,8 @@ void IndividualHost::terminate() { // prevents us from joining our `std::jthread`s on the plugin side. sockets_.close(); - host_.terminate(); - // NOTE: This leaves a zombie, because Boost.Process will actually not call - // `wait()` after we have terminated the process. - host_.wait(); + // This will also reap the terminated process + handle_.terminate(); } GroupHost::GroupHost(asio::io_context& io_context, @@ -121,7 +169,7 @@ GroupHost::GroupHost(asio::io_context& io_context, Sockets& sockets, const PluginInfo& plugin_info, const HostRequest& host_request) - : HostProcess(io_context, logger, config, sockets), + : HostProcess(io_context, sockets), plugin_info_(plugin_info), host_path_(find_vst_host(plugin_info.native_library_path_, plugin_info.plugin_arch_, @@ -156,15 +204,13 @@ GroupHost::GroupHost(asio::io_context& io_context, // new group host process. This process is detached immediately // because it should run independently of this yabridge instance as // it will likely outlive it. - bp::child group_host = - // FIXME: Boost.Filesystem conversion - launch_host(host_path_, group_socket_path.string(), - bp::env = plugin_info.create_host_env()); + Process::Handle group_host = + launch_host(host_path_, {group_socket_path.string()}, logger, + config, plugin_info); group_host.detach(); - const pid_t group_host_pid = group_host.id(); group_host_connect_handler_ = - std::jthread([this, connect, group_host_pid]() { + std::jthread([this, connect, group_host = std::move(group_host)]() { set_realtime_priority(true); pthread_setname_np(pthread_self(), "group-connect"); @@ -172,7 +218,7 @@ GroupHost::GroupHost(asio::io_context& io_context, // We'll first try to connect to the group host we just spawned // TODO: Replace this polling with inotify - while (pid_running(group_host_pid)) { + while (group_host.running()) { std::this_thread::sleep_for(20ms); try { diff --git a/src/plugin/host-process.h b/src/plugin/host-process.h index 66376c2b..cd7519c8 100644 --- a/src/plugin/host-process.h +++ b/src/plugin/host-process.h @@ -19,10 +19,8 @@ #include #include +#include #include -#include -#include -#include #include #include "../common/communication/common.h" @@ -59,108 +57,42 @@ class HostProcess { */ virtual void terminate() = 0; - /** - * Simple helper function around `boost::process::child` that launches the - * host application (`*.exe`) with some basic setup. This includes setting - * up the asynchronous pipes for STDIO redirection, closing file descriptors - * to prevent leaks, and wrapping everything in winedbg if we're compiling - * with `-Dwith-winedbg=true`. Keep in mind that winedbg does not handle - * arguments containing spaces, so most Windows paths will be split up into - * multiple arugments. - */ - template - boost::process::child launch_host(ghc::filesystem::path host_path, - Args&&... args) { - return boost::process::child( -#ifdef WITH_WINEDBG - // This is set up for KDE Plasma. Other desktop environments and - // window managers require some slight modifications to spawn a - // detached terminal emulator. Alternatively, you can spawn - // `/usr/bin/winedbg` with the `--no-start` option to launch a gdb - // server and then connect to it from another terminal. - "/usr/bin/kstart5", "konsole", "--", "-e", "winedbg", "--gdb", -#ifdef WINEDBG_LEGACY_ARGUMENT_QUOTING - // Note the double quoting here. Old versions of winedbg didn't - // respect `argv` and instead expected a pre-quoted Win32 command - // line as its arguments. - "\"" + host_path.string() + ".so\"", -#else - host_path.string() + ".so", -#endif // WINEDBG_LEGACY_ARGUMENT_QUOTING -#else - // FIXME: Replace Boost.Filesystem - host_path.string(), -#endif // WITH_WINEDBG - // FIXME: This won't work with our patched async_pipe version - // boost::process::std_out = stdout_pipe_, - // boost::process::std_err = stderr_pipe_, - patched_async_pipe_out<1, -1>(stdout_pipe_), - patched_async_pipe_out<2, -1>(stderr_pipe_), - // NOTE: If the Wine process outlives the host, then it may cause - // issues if our process is still keeping the host's file - // descriptors alive that. This can prevent Ardour from - // restarting after an unexpected shutdown. Because of this we - // won't use `vfork()`, but instead we'll just manually close - // all non-STDIO file descriptors. - // HACK: If the `disable_pipes` option is enabled, then we'll - // redirect the plugin's output to a file instead of using - // pipes to blend it in with the rest of yabridge's output. - // This is for some reason necessary for ujam's plugins and - // all other plugins made with Gorilla Engine to function. - // Otherwise they'll print a nondescriptive `JS_EXEC_FAILED` - // error message. - boost::process::extend::on_exec_setup = - [this](auto& /*executor*/) { - const int max_fds = static_cast(sysconf(_SC_OPEN_MAX)); - for (int fd = STDERR_FILENO + 1; fd < max_fds; fd++) { - close(fd); - } - - // See above - if (config_.disable_pipes) { - const int redirect_fd = - open(config_.disable_pipes->c_str(), - O_CREAT | O_APPEND | O_WRONLY, 0640); - - assert(redirect_fd != -1); - dup2(redirect_fd, STDOUT_FILENO); - dup2(redirect_fd, STDERR_FILENO); - close(redirect_fd); - } - }, - std::forward(args)...); - } - protected: /** - * Initialize the host process by setting up the STDIO redirection. + * The actual process initialization and everything involved in that process + * is done in `launch_host()` since a new process may not be required + * when using plugin groups. * - * @param io_context The IO context that the STDIO redurection will be - * handled on. - * @param logger The `Logger` instance the redirected STDIO streams will be - * written to. + * @param io_context The IO context that the STDIO redirection pipes will be + * bound to. The logging for these pipes is set up in `launch_host()`. * @param sockets The socket endpoints that will be used for communication * with the plugin. When the plugin shuts down, we'll close all of the * sockets used by the plugin. */ - HostProcess(asio::io_context& io_context, - Logger& logger, - const Configuration& config, - Sockets& sockets); + HostProcess(asio::io_context& io_context, Sockets& sockets); /** - * The STDOUT stream of the Wine process we can forward to the logger. + * Helper function that launches the Wine host application (`*.exe`) with + * all of the correct environment setup. This includes setting the correct + * environment variables for the Wine prefix the plugin is in, setting up + * pipes or files for STDIO redirection, closing file descriptors to prevent + * leaks, and wrapping all of that in a terminal process running winedbg if + * we're compiling with `-Dwith-winedbg=true`. Keep in mind that winedbg + * does not handle arguments containing spaces, so most Windows paths will + * be split up into multiple arguments. + * + * @param logger The `Logger` instance the redirected STDIO streams will be + * written to. + * @param config The plugin's configuration, used to determine whether to + * use pipes or to redirect the output to a file instead. + * @param plugin_info Information about the plugin, used to determine the + * plugin's Wine prefix. */ - patched_async_pipe stdout_pipe_; - /** - * The STDERR stream of the Wine process we can forward to the logger. - */ - patched_async_pipe stderr_pipe_; - - /** - * The current plugin instance's configuration. - */ - const Configuration& config_; + Process::Handle launch_host(const ghc::filesystem::path& host_path, + std::initializer_list args, + Logger& logger, + const Configuration& config, + const PluginInfo& plugin_info); /** * The associated sockets for the plugin we're hosting. This is used to @@ -170,9 +102,13 @@ class HostProcess { private: /** - * The logger the Wine output will be written to. + * The STDOUT stream of the Wine process we can forward to the logger. */ - Logger& logger_; + asio::posix::stream_descriptor stdout_pipe_; + /** + * The STDERR stream of the Wine process we can forward to the logger. + */ + asio::posix::stream_descriptor stderr_pipe_; asio::streambuf stdout_buffer_; asio::streambuf stderr_buffer_; @@ -218,7 +154,7 @@ class IndividualHost : public HostProcess { private: const PluginInfo& plugin_info_; ghc::filesystem::path host_path_; - boost::process::child host_; + Process::Handle handle_; }; /** diff --git a/src/plugin/utils.cpp b/src/plugin/utils.cpp index bfce1221..840842d8 100644 --- a/src/plugin/utils.cpp +++ b/src/plugin/utils.cpp @@ -20,23 +20,14 @@ #include #include -#include -#include -#include -#include #include -// XXX: With Boost 1.75 at least, this header cannot be included in alphabetical -// order because it's missing some includes -#include - // Generated inside of the build directory #include #include "../common/configuration.h" #include "../common/utils.h" -namespace bp = boost::process; namespace fs = ghc::filesystem; // These functions are used to populate the fields in `PluginInfo`. See the @@ -65,25 +56,7 @@ PluginInfo::PluginInfo(PluginType plugin_type, bool prefer_32bit_vst3) normalize_plugin_path(windows_library_path_, plugin_type)), wine_prefix_(find_wine_prefix(windows_plugin_path_)) {} -bp::environment PluginInfo::create_host_env() const { - bp::environment env = boost::this_process::environment(); - - // Only set the prefix when could auto detect it and it's not being - // overridden (this entire `std::visit` instead of `std::has_alternative` is - // just for clarity's sake) - std::visit(overload{ - [](const OverridenWinePrefix&) {}, - [&](const ghc::filesystem::path& prefix) { - env["WINEPREFIX"] = prefix.string(); - }, - [](const DefaultWinePrefix&) {}, - }, - wine_prefix_); - - return env; -} - -ProcessEnvironment PluginInfo::create_host_env_2() const { +ProcessEnvironment PluginInfo::create_host_env() const { ProcessEnvironment env(environ); // Only set the prefix when could auto detect it and it's not being @@ -130,7 +103,7 @@ std::string PluginInfo::wine_version() const { Process process(wine_path); process.arg("--version"); - process.environment(create_host_env_2()); + process.environment(create_host_env()); const auto result = process.spawn_get_stdout_line(); return std::visit( @@ -345,7 +318,6 @@ std::string create_logger_prefix(const fs::path& endpoint_base_dir) { fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path, LibArchitecture plugin_arch, bool use_plugin_groups) { - // FIXME: Anything using `this_plugin_path` and similar needs to be changed auto host_name = use_plugin_groups ? yabridge_group_host_name : yabridge_individual_host_name; if (plugin_arch == LibArchitecture::dll_32) { @@ -361,17 +333,13 @@ fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path, return host_path; } - // Boost will return an empty path if the file could not be found in the - // search path - const boost::filesystem::path vst_host_path = - bp::search_path(host_name, get_augmented_search_path()); - if (vst_host_path == "") { + if (const std::optional vst_host_path = + search_in_path(get_augmented_search_path(), host_name)) { + return *vst_host_path; + } else { throw std::runtime_error("Could not locate '" + std::string(host_name) + "'"); } - - // FIXME: Replace Boost.Filesystem usage requiring this conversion - return vst_host_path.string(); } ghc::filesystem::path generate_group_endpoint( @@ -396,8 +364,7 @@ ghc::filesystem::path generate_group_endpoint( return get_temporary_directory() / socket_name.str(); } -// FIXME: Replace Boost.Filesystem -std::vector get_augmented_search_path() { +std::vector get_augmented_search_path() { // HACK: `std::locale("")` would return the current locale, but this // overload is implementation specific, and libstdc++ returns an error // when this happens and one of the locale variables (or `LANG`) is @@ -411,6 +378,11 @@ std::vector get_augmented_search_path() { // https://svn.boost.org/trac10/changeset/72855 // // https://github.com/boostorg/process/pull/179 + // FIXME: As mentioned above, we did this in the past to work around a + // Boost.Process bug. Since we no longer use Boost.Process, we can + // technically get rid of this, but we could also leave it in place + // since this may still cause other crashes for the user if we don't + // do it. try { std::locale(""); } catch (const std::runtime_error&) { @@ -431,17 +403,19 @@ std::vector get_augmented_search_path() { setenv("LC_ALL", "C", true); // NOLINT(concurrency-mt-unsafe) } - std::vector search_path = - boost::this_process::path(); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + const char* path_env = getenv("PATH"); + assert(path_env); + + std::vector search_path = split_path(path_env); // NOLINTNEXTLINE(concurrency-mt-unsafe) if (const char* xdg_data_home = getenv("XDG_DATA_HOME")) { - search_path.push_back(boost::filesystem::path(xdg_data_home) / - "yabridge"); + search_path.push_back(fs::path(xdg_data_home) / "yabridge"); // NOLINTNEXTLINE(concurrency-mt-unsafe) } else if (const char* home_directory = getenv("HOME")) { - search_path.push_back(boost::filesystem::path(home_directory) / - ".local" / "share" / "yabridge"); + search_path.push_back(fs::path(home_directory) / ".local" / "share" / + "yabridge"); } return search_path; diff --git a/src/plugin/utils.h b/src/plugin/utils.h index d7717ec1..de434a47 100644 --- a/src/plugin/utils.h +++ b/src/plugin/utils.h @@ -18,8 +18,6 @@ #include -#include - #include "../common/configuration.h" #include "../common/plugins.h" #include "../common/process.h" @@ -76,9 +74,7 @@ struct PluginInfo { * we'll set `WINEPREFIX` to the detected Wine prefix, or it will be left * unset if we could not detect a prefix. */ - boost::process::environment create_host_env() const; - // FIXME: Replace create_host_env with this one - ProcessEnvironment create_host_env_2() const; + ProcessEnvironment create_host_env() const; /** * Return the path to the actual Wine prefix in use, taking into account @@ -236,10 +232,8 @@ ghc::filesystem::path generate_group_endpoint( * environment variable can be a big hurdle if you've never done anything like * that before. And since this is the recommended installation location, it * makes sense to also search there by default. - * - * FIXME: Replace Boost.Filesystem */ -std::vector get_augmented_search_path(); +std::vector get_augmented_search_path(); /** * Return a path to this `.so` file. This can be used to find out from where diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index 4eb73399..2ab7d3dd 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -22,6 +22,7 @@ #include "../asio-fix.h" #include +#include #include "../common/logging/common.h" #include "../utils.h"