/* PIP - Platform Independent Primitives Process Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #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] \"execve\" 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; }