diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx | 9 | ||||
-rw-r--r-- | vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx | 3 | ||||
-rw-r--r-- | vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx | 98 | ||||
-rw-r--r-- | vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx | 29 | ||||
-rw-r--r-- | vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx | 6 |
5 files changed, 101 insertions, 44 deletions
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx index 7372d476f55e..8c983996b791 100644 --- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx +++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx @@ -42,13 +42,6 @@ #include <strings.hrc> -#include <future> - -#include <boost/filesystem/path.hpp> -#include <boost/process/environment.hpp> -#include <boost/process/search_path.hpp> -#include <boost/process/io.hpp> - using namespace ::com::sun::star; using namespace ::com::sun::star::ui::dialogs; using namespace ::com::sun::star::ui::dialogs::TemplateDescription; @@ -57,8 +50,6 @@ using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::uno; -namespace bp = boost::process; -namespace bf = boost::filesystem; // helper functions diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx index 80261ded9f9b..740382d9ec49 100644 --- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx +++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx @@ -32,9 +32,6 @@ #include <rtl/ustrbuf.hxx> -#include <boost/process/child.hpp> -#include <boost/process/pipe.hpp> - #include "gtk3_kde5_filepicker_ipc.hxx" #include <functional> diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx index fd9c1c7b64e1..21690c5e74f8 100644 --- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx +++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx @@ -26,6 +26,7 @@ #include <strings.hrc> #include <future> +#include <system_error> #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> @@ -41,38 +42,33 @@ #include <unx/gtk/gtkdata.hxx> #include <boost/filesystem/path.hpp> -#include <boost/process/environment.hpp> -#include <boost/process/search_path.hpp> -#include <boost/process/io.hpp> using namespace ::com::sun::star::ui::dialogs; -namespace bp = boost::process; -namespace bf = boost::filesystem; - // helper functions namespace { -bf::path applicationDirPath() +OUString applicationDirPath() { OUString applicationFilePath; osl_getExecutableFile(&applicationFilePath.pData); OUString applicationSystemPath; osl_getSystemPathFromFileURL(applicationFilePath.pData, &applicationSystemPath.pData); - auto sysPath = applicationSystemPath.toUtf8(); - auto ret = bf::path(sysPath.getStr(), sysPath.getStr() + sysPath.getLength()); + const auto utf8Path = applicationSystemPath.toUtf8(); + auto ret = boost::filesystem::path(utf8Path.getStr(), utf8Path.getStr() + utf8Path.getLength()); ret.remove_filename(); - return ret; + return OUString::fromUtf8(OString(ret.c_str(), ret.size())); } -bf::path findPickerExecutable() +OUString findPickerExecutable() { - auto paths = boost::this_process::path(); - paths.insert(paths.begin(), applicationDirPath()); - auto ret = bp::search_path("lo_kde5filepicker", paths); - if (ret.empty()) - throw bp::process_error(std::make_error_code(std::errc::no_such_file_or_directory), + const auto path = applicationDirPath(); + const OUString app("lo_kde5filepicker"); + OUString ret; + osl_searchFileURL(app.pData, path.pData, &ret.pData); + if (ret.isEmpty()) + throw std::system_error(std::make_error_code(std::errc::no_such_file_or_directory), "could not find lo_kde5filepicker executable"); return ret; } @@ -113,16 +109,34 @@ OUString getResString(const char* pResId) // Gtk3KDE5FilePicker Gtk3KDE5FilePickerIpc::Gtk3KDE5FilePickerIpc() - // workaround: specify some non-empty argument, otherwise the Qt app will see argc == 0 - : m_process(findPickerExecutable(), "dummy", bp::std_out > m_stdout, bp::std_in < m_stdin) { + const auto exe = findPickerExecutable(); + oslProcessError result; + oslSecurity pSecurity = osl_getCurrentSecurity(); + result = osl_executeProcess_WithRedirectedIO(exe.pData, nullptr, 0, osl_Process_NORMAL, + pSecurity, nullptr, nullptr, 0, &m_process, + &m_inputWrite, &m_outputRead, nullptr); + osl_freeSecurityHandle(pSecurity); + if (result != osl_Process_E_None) + throw std::system_error(std::make_error_code(std::errc::no_such_process), + "could not start lo_kde5filepicker executable"); } Gtk3KDE5FilePickerIpc::~Gtk3KDE5FilePickerIpc() { + if (!m_process) + return; + sendCommand(Commands::Quit); - if (m_process.running()) - m_process.wait_for(std::chrono::milliseconds(100)); + TimeValue timeValue(std::chrono::milliseconds(100)); + if (osl_joinProcessWithTimeout(m_process, &timeValue) != osl_Process_E_None) + osl_terminateProcess(m_process); + + if (m_inputWrite) + osl_closeFile(m_inputWrite); + if (m_outputRead) + osl_closeFile(m_outputRead); + osl_freeProcessHandle(m_process); } sal_Int16 Gtk3KDE5FilePickerIpc::execute() @@ -198,4 +212,48 @@ void Gtk3KDE5FilePickerIpc::await(const std::future<void>& future) } } +void Gtk3KDE5FilePickerIpc::writeResponseLine(const std::string& line) +{ + sal_uInt64 bytesWritten = 0; + osl_writeFile(m_inputWrite, line.c_str(), line.size(), &bytesWritten); +} + +std::string Gtk3KDE5FilePickerIpc::readResponseLine() +{ + if (!m_responseBuffer.empty()) // check whether we have a line in our buffer + { + auto it = m_responseBuffer.find('\n'); + if (it != std::string::npos) + { + auto ret = m_responseBuffer.substr(0, it); + m_responseBuffer.erase(0, it); + return ret; + } + } + + const sal_uInt64 BUF_SIZE = 1024; + char buffer[BUF_SIZE]; + while (true) + { + sal_uInt64 bytesRead = 0; + auto err = osl_readFile(m_outputRead, buffer, BUF_SIZE, &bytesRead); + auto it = std::find(buffer, buffer + bytesRead, '\n'); + if (it != buffer + bytesRead) // check whether the chunk we read contains an EOL + { + // if so, append that part to the buffer and return it + std::string ret = m_responseBuffer.append(buffer, it); + // but keep anything else we may have read in our buffer + ++it; + m_responseBuffer.assign(it, buffer + bytesRead); + return ret; + } + // otherwise append everything we read to the buffer and try again + m_responseBuffer.append(buffer, bytesRead); + + if (err != osl_File_E_None && err != osl_File_E_AGAIN) + break; + } + return {}; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx index 8b8bfbc7a726..bed1ae113823 100644 --- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx +++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx @@ -23,32 +23,33 @@ #include <osl/conditn.hxx> #include <osl/mutex.hxx> +#include <osl/process.h> #include <rtl/ustrbuf.hxx> -#include <boost/process/child.hpp> -#include <boost/process/pipe.hpp> - #include "filepicker_ipc_commands.hxx" #include <functional> #include <future> #include <mutex> #include <thread> +#include <sstream> OUString getResString(const char* pResId); class Gtk3KDE5FilePickerIpc { protected: - boost::process::ipstream m_stdout; - boost::process::opstream m_stdin; - boost::process::child m_process; + oslProcess m_process; + oslFileHandle m_inputWrite; + oslFileHandle m_outputRead; // simple multiplexing: every command gets it's own ID that can be used to // read the corresponding response uint64_t m_msgId = 1; std::mutex m_mutex; uint64_t m_incomingResponse = 0; + std::string m_responseBuffer; + std::stringstream m_responseStream; public: explicit Gtk3KDE5FilePickerIpc(); @@ -56,14 +57,20 @@ public: sal_Int16 execute(); + void writeResponseLine(const std::string& line); + template <typename... Args> uint64_t sendCommand(Commands command, const Args&... args) { auto id = m_msgId; ++m_msgId; - sendIpcArgs(m_stdin, id, command, args...); + std::stringstream stream; + sendIpcArgs(stream, id, command, args...); + writeResponseLine(stream.str()); return id; } + std::string readResponseLine(); + template <typename... Args> void readResponse(uint64_t id, Args&... args) { // read synchronously from a background thread and run the eventloop until the value becomes available @@ -76,12 +83,16 @@ public: // check if we need to read (and potentially wait) a response ID if (m_incomingResponse == 0) - readIpcArgs(m_stdout, m_incomingResponse); + { + m_responseStream.clear(); + m_responseStream.str(readResponseLine()); + readIpcArgs(m_responseStream, m_incomingResponse); + } if (m_incomingResponse == id) { // the response we are waiting for came in - readIpcArgs(m_stdout, args...); + readIpcArgs(m_responseStream, args...); m_incomingResponse = 0; break; } diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx index bed2c049aa3a..d3f797ce9234 100644 --- a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx +++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx @@ -22,7 +22,7 @@ #include "gtk3_kde5_filepicker.hxx" #include "gtk3_kde5_folderpicker.hxx" -#include <boost/process/exception.hpp> +#include <system_error> uno::Reference<ui::dialogs::XFilePicker2> GtkInstance::createFilePicker(const uno::Reference<uno::XComponentContext>& xMSF) @@ -31,7 +31,7 @@ GtkInstance::createFilePicker(const uno::Reference<uno::XComponentContext>& xMSF { return uno::Reference<ui::dialogs::XFilePicker2>(new Gtk3KDE5FilePicker(xMSF)); } - catch (const boost::process::process_error& error) + catch (const std::system_error& error) { OSL_FAIL(error.what()); return { nullptr }; @@ -45,7 +45,7 @@ GtkInstance::createFolderPicker(const uno::Reference<uno::XComponentContext>& xM { return uno::Reference<ui::dialogs::XFolderPicker2>(new Gtk3KDE5FolderPicker(xMSF)); } - catch (const boost::process::process_error& error) + catch (const std::system_error& error) { OSL_FAIL(error.what()); return { nullptr }; |