diff options
author | Alexander Gluzsky <sss123next@list.ru> | 2013-02-08 14:27:01 +0000 |
---|---|---|
committer | Alexander Gluzsky <sss123next@list.ru> | 2013-02-08 14:27:01 +0000 |
commit | 4d20cb679ac6ca7efd23bc9ad99d33fc8794f693 (patch) | |
tree | c9279611b2ec59e03102a0520654e0b482e74c64 /plugins/New_GPG/src/gpg_wrapper.cpp | |
parent | 8ba05a620bebb8f1400b20148be7012243e2ff9f (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-x | plugins/New_GPG/src/gpg_wrapper.cpp | 195 |
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 ¶ms) +{ + pxExecute(params.aargv, params.out, params.code, params.result, params.child); +} + +bool gpg_launcher(gpg_execution_params ¶ms, 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); } |