comparison host/tools/Utils/common/Subprocess.cpp @ 84:489eb5632bc3 ecos-sw-2000-04-28

Merge from eCos master repository on 2000-04-28-18:44:39-BST
author jlarmour
date Fri, 28 Apr 2000 18:18:36 +0000
parents 6736c52df507
children 4c750ce71ae3
comparison
equal deleted inserted replaced
83:1094d5fdd3e0 84:489eb5632bc3
66 m_idProcess(0), 66 m_idProcess(0),
67 m_pLogparam(0), 67 m_pLogparam(0),
68 m_pfnLogfunc(0), 68 m_pfnLogfunc(0),
69 m_bKillThread(false) 69 m_bKillThread(false)
70 { 70 {
71 #ifdef _WIN32 71 #ifdef _WIN32
72 InitializeCriticalSection(&m_cs); 72 m_hProcess=0;
73 #endif 73 #endif
74 } 74 }
75 75
76 CSubprocess::~CSubprocess() 76 CSubprocess::~CSubprocess()
77 { 77 {
78 Kill(); 78 Kill();
79 if(!CeCosThreadUtils::WaitFor(m_bThreadTerminated,1000)){ 79 if(!CeCosThreadUtils::WaitFor(m_bThreadTerminated,1000)){
80 m_bKillThread=true; 80 m_bKillThread=true;
81 CeCosThreadUtils::WaitFor(m_bThreadTerminated); 81 CeCosThreadUtils::WaitFor(m_bThreadTerminated);
82 } 82 }
83 #ifdef _WIN32 83 #ifdef _WIN32
84 DeleteCriticalSection(&m_cs); 84 if(m_hProcess){
85 #endif 85 CloseHandle(m_hProcess);
86 }
87 #endif
86 } 88 }
87 89
88 bool CSubprocess::Run(LogFunc *pfnLog,void * pLogparam, LPCTSTR pszCmd,bool bBlock/*=true*/) 90 bool CSubprocess::Run(LogFunc *pfnLog,void * pLogparam, LPCTSTR pszCmd,bool bBlock/*=true*/)
89 { 91 {
90 bool rc; 92 bool rc;
94 m_pfnLogfunc=pfnLog; 96 m_pfnLogfunc=pfnLog;
95 m_pLogparam=pLogparam; 97 m_pLogparam=pLogparam;
96 #ifdef _WIN32 98 #ifdef _WIN32
97 // UNIX does it from the thread func. WIN32 could too, but it's nice to know at the time 99 // UNIX does it from the thread func. WIN32 could too, but it's nice to know at the time
98 // of calling run whether the process is successfully created. 100 // of calling run whether the process is successfully created.
101 if(m_hProcess){
102 // Normally done in the dtor
103 CloseHandle(m_hProcess);
104 }
99 rc=CreateProcess(pszCmd); 105 rc=CreateProcess(pszCmd);
100 #else 106 #else
101 m_strCmd=pszCmd; 107 m_strCmd=pszCmd;
102 rc=true; 108 rc=true;
103 #endif 109 #endif
222 m_idProcess=pi.dwProcessId; 228 m_idProcess=pi.dwProcessId;
223 m_hProcess=pi.hProcess; 229 m_hProcess=pi.hProcess;
224 if(m_bVerbose){ 230 if(m_bVerbose){
225 Output(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline)); 231 Output(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline));
226 } 232 }
227 TRACE(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline)); 233 TRACE(String::SFormat(_T("Process %d created \"%s\"\n"),m_idProcess,pszCmdline));
228 m_nExitCode=STILL_ACTIVE; 234 m_nExitCode=STILL_ACTIVE;
229 CloseHandle(pi.hThread); 235 CloseHandle(pi.hThread);
230 } else { 236 } else {
231 m_idProcess=0; 237 m_idProcess=0;
232 if(m_bVerbose){ 238 if(m_bVerbose){
233 Output(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString())); 239 Output(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString()));
234 } 240 }
235 TRACE(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString())); 241 TRACE(String::SFormat(_T("Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString()));
236 m_nExitCode=GetLastError(); 242 m_nExitCode=GetLastError();
237 CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE; 243 CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE;
238 CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; 244 CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE;
239 } 245 }
240 246
299 TRACE(_T("Finished reading from process %d (%s)\n"),m_idProcess,(LPCTSTR)str); 305 TRACE(_T("Finished reading from process %d (%s)\n"),m_idProcess,(LPCTSTR)str);
300 #endif 306 #endif
301 307
302 CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE; 308 CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE;
303 CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; 309 CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE;
304 EnterCriticalSection(&m_cs);
305 CloseHandle(m_hProcess);
306 m_hProcess=0; // Do not use INVALID_HANDLE_VALUE, which is also the pseudo-handle returned by GetCurrentProcess()
307 LeaveCriticalSection(&m_cs);
308 310
309 if(m_bAutoDelete){ 311 if(m_bAutoDelete){
310 m_bThreadTerminated=true; // or else the dtor will block 312 m_bThreadTerminated=true; // or else the dtor will block
311 delete this; 313 delete this;
312 } 314 }
494 PSExtract(arPinfo); 496 PSExtract(arPinfo);
495 } 497 }
496 498
497 #ifdef _WIN32 499 #ifdef _WIN32
498 500
499 EnterCriticalSection(&m_cs); // because the thread func may be closing it
500 if(m_hProcess){ 501 if(m_hProcess){
501 TRACE(_T("Terminate m_idProcess %d [%s]\n"),m_idProcess,(LPCTSTR)Name(m_idProcess)); 502 TRACE(_T("Terminate process %s\n"),(LPCTSTR)Name(m_idProcess));
502 rc=(TRUE==::TerminateProcess(m_hProcess,PROCESS_KILL_EXIT_CODE)); 503 rc=(TRUE==::TerminateProcess(m_hProcess,PROCESS_KILL_EXIT_CODE));
503 // Threadfunc's responsibility alone to close the handle 504 // dtor's (or subsequent Run's) responsibility to close the handle
504 } 505 }
505 LeaveCriticalSection(&m_cs); 506
506 #else 507 #else
507 rc=(0==kill(m_idProcess,SIGTERM)); 508 rc=(0==kill(m_idProcess,SIGTERM));
508 int status; 509 int status;
509 waitpid(m_idProcess,&status,WNOHANG); 510 waitpid(m_idProcess,&status,WNOHANG);
510 #endif 511 #endif
522 continue; 523 continue;
523 } 524 }
524 // end hack 525 // end hack
525 HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID); 526 HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID);
526 if(hProcess){ 527 if(hProcess){
527 TRACE(_T("Terminate m_idProcess %d [%s]\n"),arPinfo[i].PID,(LPCTSTR)Name(arPinfo[i].PID)); 528 TRACE(_T("Terminate process %s\n"),(LPCTSTR)Name(arPinfo[i].PID));
528
529 rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE)); 529 rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE));
530 CloseHandle(hProcess); 530 CloseHandle(hProcess);
531 } else { 531 } else {
532 rc=false; 532 rc=false;
533 } 533 }
548 Time t=0; 548 Time t=0;
549 // kill process *and* its children 549 // kill process *and* its children
550 // FIXME: needs to be top-down 550 // FIXME: needs to be top-down
551 551
552 #ifdef _WIN32 552 #ifdef _WIN32
553 EnterCriticalSection(&m_cs); // because the thread func may be closing it
554 __int64 ftCreation,ftExit,ftKernel,ftUser; 553 __int64 ftCreation,ftExit,ftKernel,ftUser;
555 if(m_hProcess && ::GetProcessTimes (m_hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ 554 if(m_hProcess && ::GetProcessTimes (m_hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){
556 t+=Time((ftKernel+ftUser)/10000); 555 t+=Time((ftKernel+ftUser)/10000);
557 } 556 }
558 LeaveCriticalSection(&m_cs);
559 557
560 if(bRecurse){ 558 if(bRecurse){
561 PInfoArray arPinfo; 559 PInfoArray arPinfo;
562 PSExtract(arPinfo); 560 PSExtract(arPinfo);
563 if(m_idProcess && -1!=m_idProcess){ 561 if(m_idProcess && -1!=m_idProcess){
687 break; 685 break;
688 } 686 }
689 687
690 SetParents(arPinfo); 688 SetParents(arPinfo);
691 689
692 /*
693 for(int k=0;k<(signed)arPinfo.size();k++){
694 const PInfo &p=arPinfo[k];
695 TRACE(_T("%d%c pid=%4d ppid=%4d t=%I64d [%s]\n"),k,p.IsChildOf(GetCurrentProcessId())?_TCHAR('*'):_TCHAR(':'),p.PID,p.PPID,p.t,(LPCTSTR)Name(p.PID));
696 }
697 */
698 if(!rc){ 690 if(!rc){
699 ERROR(_T("Couldn't get process information!\n")); 691 ERROR(_T("Couldn't get process information!\n"));
700 } 692 }
701 return rc; 693 return rc;
702 } 694 }
778 770
779 if(bCircularity){ 771 if(bCircularity){
780 ERROR(_T("!!! Circularly linked process list at index %d\n"),i); 772 ERROR(_T("!!! Circularly linked process list at index %d\n"),i);
781 for(int k=0;k<(signed)arPinfo.size();k++){ 773 for(int k=0;k<(signed)arPinfo.size();k++){
782 const PInfo &p=arPinfo[k]; 774 const PInfo &p=arPinfo[k];
783 ERROR(_T("%d: pid=%4d ppid=%4d [%s]\n"),k,p.PID,p.PPID,(LPCTSTR)Name(p.PID)); 775 ERROR(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID);
784 } 776 }
785 } 777 }
786 } 778 }
787 779
788 bool CSubprocess::PInfo::IsChildOf(int pid) const 780 bool CSubprocess::PInfo::IsChildOf(int pid) const
795 return false; 787 return false;
796 } 788 }
797 789
798 const String CSubprocess::Name(int pid) 790 const String CSubprocess::Name(int pid)
799 { 791 {
800 String str; 792 String str(String::SFormat(_T("id=%d"),pid));
801 #ifdef _DEBUG 793 #ifdef _DEBUG
802 #ifdef _WIN32 794 #ifdef _WIN32
803 if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){ 795 if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){
804 static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) = 796 static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) =
805 (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib1,"EnumProcessModules" ) ; 797 (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib1,"EnumProcessModules" ) ;
810 if(hProcess) { 802 if(hProcess) {
811 HMODULE hMod; 803 HMODULE hMod;
812 DWORD dwSize; 804 DWORD dwSize;
813 if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){ 805 if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){
814 // Get Full pathname: 806 // Get Full pathname:
815 LPTSTR buf=str.GetBuffer(MAX_PATH); 807 TCHAR buf[1+MAX_PATH];
816 lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH); 808 lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH);
817 str.ReleaseBuffer(); 809 str+=_TCHAR(' ');
810 str+=buf;
818 } 811 }
819 CloseHandle(hProcess); 812 CloseHandle(hProcess);
820 } 813 }
821 } 814 }
822 } 815 }