Mercurial > flash_v2
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 } |
