summaryrefslogtreecommitdiff
path: root/plugins/New_GPG/src/gpg_wrapper.cpp
diff options
context:
space:
mode:
authorAlexander Gluzsky <sss123next@list.ru>2013-02-08 14:27:01 +0000
committerAlexander Gluzsky <sss123next@list.ru>2013-02-08 14:27:01 +0000
commit4d20cb679ac6ca7efd23bc9ad99d33fc8794f693 (patch)
treec9279611b2ec59e03102a0520654e0b482e74c64 /plugins/New_GPG/src/gpg_wrapper.cpp
parent8ba05a620bebb8f1400b20148be7012243e2ff9f (diff)
"boosted" process management
misc process management optimizations (should be little faster now) git-svn-id: http://svn.miranda-ng.org/main/trunk@3479 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/New_GPG/src/gpg_wrapper.cpp')
-rwxr-xr-xplugins/New_GPG/src/gpg_wrapper.cpp195
1 files changed, 82 insertions, 113 deletions
diff --git a/plugins/New_GPG/src/gpg_wrapper.cpp b/plugins/New_GPG/src/gpg_wrapper.cpp
index e110f74c73..5f9df7dfd1 100755
--- a/plugins/New_GPG/src/gpg_wrapper.cpp
+++ b/plugins/New_GPG/src/gpg_wrapper.cpp
@@ -15,64 +15,16 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
-
//thx gpg module from Harald Treder, Zakhar V. Bardymov
-//boost::mutex gpg_mutex;
-
-pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr)
+pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD aexitcode, pxResult *result, boost::process::child *_child)
{
-// gpg_mutex.lock();
if(!gpg_valid)
return pxNotConfigured;
extern logtofile debuglog;
- BOOL success;
- STARTUPINFO sinfo = {0};
- SECURITY_ATTRIBUTES sattrs = {0};
- SECURITY_DESCRIPTOR sdesc = {0};
- PROCESS_INFORMATION pri = {0};
- HANDLE newstdin, newstdout, readstdout, writestdin;
- char *inputpos;
- unsigned long transfered;
- int size;
-
- wstring commandline;
-
- sattrs.nLength=sizeof(SECURITY_ATTRIBUTES);
- sattrs.bInheritHandle=TRUE;
- InitializeSecurityDescriptor(&sdesc,SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&sdesc,TRUE,NULL,FALSE);
- sattrs.lpSecurityDescriptor=&sdesc;
-
- success=CreatePipe(&newstdin,&writestdin,&sattrs,0);
- if (!success)
- {
- *result = pxCreatePipeFailed;
- return pxCreatePipeFailed;
- }
-
- success=CreatePipe(&readstdout,&newstdout,&sattrs,0);
- if (!success)
- {
- CloseHandle(newstdin);
- CloseHandle(writestdin);
- *result = pxCreatePipeFailed;
- return pxCreatePipeFailed;
- }
-
- GetStartupInfo(&sinfo);
- sinfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- sinfo.wShowWindow=SW_HIDE;
- sinfo.hStdOutput=newstdout;
- sinfo.hStdError=newstdout;
- sinfo.hStdInput=newstdin;
-
- char *mir_path = new char [MAX_PATH];
- CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
- SetCurrentDirectoryA(mir_path);
- delete [] mir_path;
+
TCHAR *bin_path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T(""));
{
if(!boost::filesystem::exists(bin_path))
@@ -84,98 +36,114 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD
return pxNotFound;
}
}
- TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
- { //form initial command
- commandline += _T("\"");
- commandline += bin_path;
- commandline += _T("\" --homedir \"");
- commandline += home_dir;
- commandline += _T("\" ");
- commandline += _T("--display-charset utf-8 ");
- commandline += _T("-z 9 ");
- commandline += *acommandline;
- mir_free(bin_path);
- mir_free(home_dir);
- }
- if(bDebugLog)
- debuglog<<std::string(time_str()+": gpg in: "+toUTF8(commandline));
+ using namespace boost::process;
+ using namespace boost::process::initializers;
+ using namespace boost::iostreams;
- success = CreateProcess(NULL, (TCHAR*)commandline.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, (void*)_T("LANGUAGE=en@quot\0LC_ALL=English\0"), NULL, &sinfo, &pri);
- if (!success)
+ std::vector<std::wstring> argv;
+ std::vector<std::wstring> env;
+ env.push_back(L"LANGUAGE=en@quot");
+ env.push_back(L"LC_ALL=English");
+ argv.push_back(bin_path);
+ argv.push_back(L"--homedir");
+ TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ argv.push_back(home_dir);
+ mir_free(home_dir);
+ argv.push_back(L"--display-charset");
+ argv.push_back(L"utf-8");
+ argv.push_back(L"-z9");
+ argv.insert(argv.end(), aargv.begin(), aargv.end());
+
+ if(bDebugLog)
{
- CloseHandle(newstdin);
- CloseHandle(writestdin);
- CloseHandle(newstdout);
- CloseHandle(readstdout);
- if(bDebugLog)
- debuglog<<time_str()<<": Failed to create process\n";
-// gpg_mutex.unlock();
- *result = pxCreateProcessFailed;
- return pxCreateProcessFailed;
+ std::wstring args;
+ for(int i = 0; i < argv.size(); ++i)
+ {
+ args += argv[i];
+ args += L" ";
+ }
+ args.erase(args.size()-1, 1);
+ debuglog<<std::string(time_str()+": gpg in: "+toUTF8(args));
}
- hProcess = pri.hProcess;
-
- inputpos=ainput;
- while (true)
+ pipe pout = create_pipe();
{
- if(!pri.hProcess)
- break;
- success=GetExitCodeProcess(pri.hProcess,aexitcode);
- if (success && *aexitcode!=STILL_ACTIVE)
- break;
+ file_descriptor_sink sout(pout.sink, close_handle);
- storeOutput(readstdout,aoutput);
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
- if (*inputpos!='\0') size=1;
- else size=0;
+ child c = execute(set_args(argv), bind_stdout(sout), /*bind_stdin(sin),*/ show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+ _child = &c;
- success=WriteFile(writestdin,inputpos,size,&transfered,NULL);
- inputpos+=transfered;
- boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+ delete [] mir_path;
+ auto ec = wait_for_exit(*_child);
+ *aexitcode = ec;
+ _child = nullptr;
}
+
+ file_descriptor_source source(pout.source, close_handle);
- storeOutput(readstdout,aoutput);
+ stream<file_descriptor_source> is(source);
+ try{
+ std::string s;
+ while(std::getline(is, s))
+ {
+ aoutput->append(s);
+ aoutput->append("\n");
+ }
+ }
+ catch(const std::exception &e)
+ {
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": failed to read from stream with error: " + e.what() + "\n\tSuccesfully read : " + *aoutput);
+ }
fix_line_term(*aoutput);
if(bDebugLog)
debuglog<<std::string(time_str()+": gpg out: "+*aoutput);
- WaitForSingleObject(pri.hProcess,INFINITE);
-
- CloseHandle(pri.hThread);
- CloseHandle(pri.hProcess);
- CloseHandle(newstdin);
- CloseHandle(newstdout);
- CloseHandle(readstdout);
- CloseHandle(writestdin);
- *result = pxSuccess;
-// gpg_mutex.unlock();
if(*aexitcode)
{
if(bDebugLog)
debuglog<<std::string(time_str()+": warning: wrong gpg exit status, gpg output: "+*aoutput);
return pxSuccessExitCodeInvalid;
}
+
+
return pxSuccess;
}
-void pxEexcute_thread(void *param)
+void pxEexcute_thread(gpg_execution_params &params)
+{
+ pxExecute(params.aargv, params.out, params.code, params.result, params.child);
+}
+
+bool gpg_launcher(gpg_execution_params &params, boost::posix_time::time_duration t)
{
- gpg_execution_params *params = (gpg_execution_params*)param;
- pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result, params->hProcess, params->proc);
+ bool ret = true;
+ boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, params));
+ if(!gpg_thread->timed_join(t))
+ {
+ ret = false;
+ delete gpg_thread;
+ if(params.child)
+ boost::process::terminate(*(params.child));
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG execution timed out, aborted");
+ }
+ return ret;
}
-pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr, string &old_pass, string &new_pass)
+pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD aexitcode, pxResult *result, boost::process::child *_child, string &old_pass, string &new_pass)
{
-// gpg_mutex.lock();
if(!gpg_valid)
return pxNotConfigured;
extern logtofile debuglog;
@@ -212,16 +180,16 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput,
argv.insert(argv.end(), aargv.begin(), aargv.end());
// pipe pout = create_pipe();
- pipe pin = create_pipe();
+// pipe pin = create_pipe();
// file_descriptor_sink sout(pout.sink, close_handle);
- file_descriptor_source sin(pin.source, close_handle);
+// file_descriptor_source sin(pin.source, close_handle);
char *mir_path = new char [MAX_PATH];
CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
//execute(set_args(argv), bind_stdout(sout), bind_stdin(sin), show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
- child c = execute(set_args(argv), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
- //child c = execute(run_exe("c:\\windows\\system32\\cmd.exe"), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+ child c = execute(set_args(argv), /*bind_stdin(sin), */inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+ _child = &c;
delete [] mir_path;
@@ -241,7 +209,8 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput,
// out<<toUTF8(cmd)<<std::endl;
//fucked gpg does not want to give us stdin/stdout
- wait_for_exit(c);
+ wait_for_exit(*_child);
+ _child = nullptr;
/* out<<old_pass<<std::endl;
out<<new_pass<<std::endl;
@@ -342,5 +311,5 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput,
void pxEexcute_passwd_change_thread(void *param)
{
gpg_execution_params_pass *params = (gpg_execution_params_pass*)param;
- pxResult result = pxExecute_passwd_change(params->args, params->useless, params->out, params->code, params->result, params->hProcess, params->proc, params->old_pass, params->new_pass);
+ pxResult result = pxExecute_passwd_change(params->args, params->out, params->code, params->result, params->child, params->old_pass, params->new_pass);
}