102 lines
1.9 KiB
C++
102 lines
1.9 KiB
C++
#include "dl_process.h"
|
||
|
||
#include <cpp-subprocess/subprocess.hpp>
|
||
using namespace subprocess;
|
||
|
||
#include "memory/dl_code_cvt.h"
|
||
#include "io/dl_log.h"
|
||
#include "base/dl_string.h"
|
||
#include "dl_time.h"
|
||
|
||
namespace dl
|
||
{
|
||
bool Process::Exec(const std::vector<std::string>& cmd, Result& result)
|
||
{
|
||
try
|
||
{
|
||
Popen p = Popen(cmd, output{ PIPE });
|
||
// 等待结束,并读取管道
|
||
result._str = p.communicate().first.buf.data();
|
||
result._exitCode = p.retcode();
|
||
return true;
|
||
}
|
||
catch (CalledProcessError& e)
|
||
{
|
||
log_err("创建进程失败{},{}", dl::to_string(cmd), dl::to_string(e.what()));
|
||
}
|
||
catch (...)
|
||
{
|
||
log_err0("未知异常!");
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool Process::ExecMulti(const std::vector<std::string>& cmd, Instance& instance)
|
||
{
|
||
try
|
||
{
|
||
instance._p = new Popen(cmd, output{ PIPE }, input{ PIPE });
|
||
}
|
||
catch (CalledProcessError& e)
|
||
{
|
||
log_err("创建进程失败{},{}", dl::to_string(cmd), dl::to_string(e.what()));
|
||
}
|
||
catch (...)
|
||
{
|
||
log_err0("未知异常!");
|
||
}
|
||
|
||
instance._thread = g_thread->Create();
|
||
instance._thread->Start(_thread_exec, &instance);
|
||
|
||
return true;
|
||
}
|
||
|
||
void Process::Send(Instance& instance, std::string_view str)
|
||
{
|
||
instance._p->send(std::string{ str } + '\n');
|
||
fflush(instance._p->input());
|
||
}
|
||
|
||
void Process::_thread_exec(void* p)
|
||
{
|
||
Instance& instance = *(Instance*)p;
|
||
|
||
while (true)
|
||
{
|
||
std::string str = Process::_read(instance);
|
||
if(str.empty())
|
||
break;
|
||
instance._mutexRet.lock();
|
||
instance._result._str += str;
|
||
instance._mutexRet.unlock();
|
||
instance._listLine.Add(String::EraseEndl(str));
|
||
g_time->Sleep();
|
||
}
|
||
}
|
||
|
||
std::string Process::_read(Instance& instance)
|
||
{
|
||
std::string ret;
|
||
char buf[1024];
|
||
while (fgets(buf, sizeof(buf), instance._p->output()))
|
||
{
|
||
ret += buf;
|
||
if(ret.back() == '\n')
|
||
return ret;
|
||
}
|
||
// eof or error
|
||
return ret;
|
||
}
|
||
|
||
|
||
Process::Instance::~Instance()
|
||
{
|
||
_p->kill();
|
||
delete _p;
|
||
delete _thread;
|
||
}
|
||
|
||
}
|