174 lines
4.3 KiB
C++
174 lines
4.3 KiB
C++
#include "piprocess.h"
|
|
|
|
|
|
PIProcess::PIProcess(): PIThread() {
|
|
exit_code = -1;
|
|
#ifdef WINDOWS
|
|
pi.dwProcessId = 0;
|
|
#else
|
|
pid = 0;
|
|
#endif
|
|
is_exec = false;
|
|
g_in = g_out = g_err = false;
|
|
t_in = t_out = t_err = false;
|
|
env = PIProcess::currentEnvironment();
|
|
}
|
|
|
|
|
|
PIProcess::~PIProcess() {
|
|
if (t_in) f_in.remove();
|
|
if (t_out) f_out.remove();
|
|
if (t_err) f_err.remove();
|
|
}
|
|
|
|
|
|
void PIProcess::exec_() {
|
|
is_exec = false;
|
|
startOnce();
|
|
//cout << "exec wait" << endl;
|
|
while (!is_exec)
|
|
msleep(1);
|
|
//cout << "exec end" << endl;
|
|
}
|
|
|
|
|
|
void PIProcess::run() {
|
|
//cout << "run" << endl;
|
|
string str;
|
|
/// arguments convertion
|
|
int as = 0;
|
|
#ifdef WINDOWS
|
|
//args.pop_front();
|
|
piForeachC (PIString & i, args)
|
|
as += i.stdString().length() + 1;
|
|
char * a = new char[as];
|
|
memset(a, ' ', as - 1);
|
|
as = 0;
|
|
for (int i = 0; i < args.size_s(); ++i) {
|
|
str = args[i].stdString();
|
|
memcpy(&a[as], str.c_str(), str.size());
|
|
as += str.length() + 1;
|
|
}
|
|
a[as - 1] = 0;
|
|
#else
|
|
char * a[args.size_s() + 1];
|
|
for (int i = 0; i < args.size_s(); ++i) {
|
|
str = args[i].stdString();
|
|
a[i] = new char[str.size() + 1];
|
|
memcpy(a[i], str.c_str(), str.size());
|
|
a[i][str.size()] = 0;
|
|
//cout << a[i] << endl;
|
|
}
|
|
a[args.size_s()] = 0;
|
|
#endif
|
|
/// environment convertion
|
|
char ** e = new char*[env.size_s() + 1];
|
|
for (int i = 0; i < env.size_s(); ++i) {
|
|
str = env[i].stdString();
|
|
e[i] = new char[str.size() + 1];
|
|
memcpy(e[i], str.c_str(), str.size());
|
|
e[i][str.size()] = 0;
|
|
//cout << e[i] << endl;
|
|
}
|
|
e[env.size_s()] = 0;
|
|
/// files for stdin/out/err
|
|
t_in = t_out = t_err = false;
|
|
if (f_in.path().isEmpty()) {
|
|
f_in = PIFile::openTemporary(PIFile::New | PIFile::Read);
|
|
t_in = true;
|
|
}
|
|
f_in.open(PIFile::New | PIFile::Read); f_in.close();
|
|
if (f_out.path().isEmpty()) {
|
|
f_out = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
|
t_out = true;
|
|
}
|
|
f_out.open(PIFile::New | PIFile::Write); f_out.close();
|
|
if (f_err.path().isEmpty()) {
|
|
f_err = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
|
t_err = true;
|
|
}
|
|
f_err.open(PIFile::New | PIFile::Write); f_err.close();
|
|
|
|
str = args.front().stdString();
|
|
is_exec = true;
|
|
#ifndef WINDOWS
|
|
pid = fork();
|
|
if (pid == 0) {
|
|
#endif
|
|
FILE * tf;
|
|
//cout << "exec" << endl;
|
|
//cout << f_out.path() << endl;
|
|
if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
|
|
if (g_out) tf = freopen(f_out.path().data(), "w", stdout);
|
|
if (g_err) tf = freopen(f_err.path().data(), "w", stderr);
|
|
#ifndef WINDOWS
|
|
if (!wd.isEmpty()) as = chdir(wd.data());
|
|
#endif
|
|
#ifdef WINDOWS
|
|
GetStartupInfoA(&si);
|
|
memset(&pi, 0, sizeof(pi));
|
|
if(CreateProcessA(0, // No module name (use command line)
|
|
a, // Command line
|
|
0, // Process handle not inheritable
|
|
0, // Thread handle not inheritable
|
|
false, // Set handle inheritance to FALSE
|
|
0, // No creation flags
|
|
0,//e, // Use environment
|
|
wd.isEmpty() ? 0 : wd.data(), // Use working directory
|
|
&si, // Pointer to STARTUPINFO structure
|
|
&pi)) // Pointer to PROCESS_INFORMATION structure
|
|
{
|
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
|
CloseHandle(pi.hProcess);
|
|
} else
|
|
cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
|
#else
|
|
if (execve(str.c_str(), a, e) < 0)
|
|
cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl;
|
|
} else {
|
|
msleep(1);
|
|
//cout << "wait" << endl;
|
|
wait(&exit_code);
|
|
pid = 0;
|
|
//cout << "wait done" << endl;
|
|
}
|
|
#endif
|
|
is_exec = false;
|
|
for (int i = 0; i < env.size_s(); ++i)
|
|
delete e[i];
|
|
delete e;
|
|
#ifdef WINDOWS
|
|
delete a;
|
|
#else
|
|
for (int i = 0; i < args.size_s(); ++i)
|
|
delete a[i];
|
|
#endif
|
|
//cout << "end" << endl;
|
|
}
|
|
|
|
|
|
void PIProcess::removeEnvironmentVariable(const PIString & variable) {
|
|
PIString s;
|
|
for (int i = 0; i < env.size_s(); ++i) {
|
|
s = env[i];
|
|
if (s.left(s.find("=")).trimmed() == variable) {
|
|
env.remove(i);
|
|
--i;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PIProcess::setEnvironmentVariable(const PIString & variable, const PIString & value) {
|
|
PIString s, v;
|
|
for (int i = 0; i < env.size_s(); ++i) {
|
|
s = env[i];
|
|
v = s.left(s.find("=")).trimmed();
|
|
if (v == variable) {
|
|
env[i] = v + "=" + value;
|
|
return;
|
|
}
|
|
}
|
|
env << variable + "=" + value;
|
|
}
|