- fixes for process output reading

This commit is contained in:
Dmytro Bogovych 2018-10-01 10:23:39 +03:00
parent 2564e690e8
commit c7da260b9b
3 changed files with 27 additions and 9 deletions

View File

@ -81,6 +81,7 @@ std::string OsProcess::execCommand(const std::string& cmd)
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <sys/select.h>
std::string OsProcess::execCommand(const std::string& cmd) std::string OsProcess::execCommand(const std::string& cmd)
{ {
@ -100,22 +101,35 @@ std::string OsProcess::execCommand(const std::string& cmd)
return result; return result;
} }
void OsProcess::asyncExecCommand(const std::string& cmdline, #include <poll.h>
std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdline,
std::function<void(const std::string& line)> callback, std::function<void(const std::string& line)> callback,
bool& finish_flag) bool& finish_flag)
{ {
std::thread t([cmdline, callback, &finish_flag]() std::shared_ptr<std::thread> t = std::make_shared<std::thread>([cmdline, callback, &finish_flag]()
{ {
std::string cp = cmdline; std::string cp = cmdline;
std::shared_ptr<FILE> pipe(popen(cp.c_str(), "r"), pclose); FILE* pipe = popen(cp.c_str(), "r");
if (!pipe) if (!pipe)
throw std::runtime_error("Failed to run."); throw std::runtime_error("Failed to run.");
char buffer[1024]; char buffer[1024];
std::string result = ""; std::string result = "";
while (!feof(pipe.get()) && !finish_flag) int f = fileno(pipe);
while (!feof(pipe) && !finish_flag)
{ {
if (fgets(buffer, 1024, pipe.get()) != nullptr) // Wait for more data
struct pollfd pfd{ .fd = f, .events = POLLIN };
while (poll(&pfd, 1, 0) == 0 && !finish_flag)
;
// Read data
if (finish_flag)
continue;
if (fgets(buffer, 1024, pipe) != nullptr)
{ {
if (callback) if (callback)
callback(buffer); callback(buffer);
@ -123,11 +137,13 @@ void OsProcess::asyncExecCommand(const std::string& cmdline,
} }
} }
if (pipe)
pclose(pipe);
finish_flag = true; finish_flag = true;
}); });
while (!finish_flag) return t;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
#endif #endif

View File

@ -3,12 +3,14 @@
#include <string> #include <string>
#include <functional> #include <functional>
#include <memory>
#include <thread>
class OsProcess class OsProcess
{ {
public: public:
static std::string execCommand(const std::string& cmdline); static std::string execCommand(const std::string& cmdline);
static void asyncExecCommand(const std::string& cmdline, static std::shared_ptr<std::thread> asyncExecCommand(const std::string& cmdline,
std::function<void(const std::string& line)> callback, std::function<void(const std::string& line)> callback,
bool& finish_flag); bool& finish_flag);

View File

@ -123,7 +123,7 @@ BufferQueue::Block BufferQueue::pull(std::chrono::milliseconds timeout)
std::unique_lock<std::mutex> l(mMutex); std::unique_lock<std::mutex> l(mMutex);
std::cv_status status = mBlockList.empty() ? std::cv_status::timeout : std::cv_status::no_timeout; std::cv_status status = mBlockList.empty() ? std::cv_status::timeout : std::cv_status::no_timeout;
while (mBlockList.empty() && status == std::cv_status::timeout) if (mBlockList.empty())
status = mSignal.wait_for(l, timeout); status = mSignal.wait_for(l, timeout);
Block r; Block r;