⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subprocess.cpp

📁 移植到WLIT项目的redboot源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
          break;          case 0:          goto Done;          continue;        default:          buf[rc]=_TCHAR('\0');          Output(String::CStrToUnicodeStr(buf));          continue;      }    } while(!m_bKillThread && m_pfnContinue(m_pContinuationFuncParam));Done:    TRACE(_T("Closing fd %d\n"),m_tty);    close (m_tty);      switch(waitpid(m_idProcess,&m_nExitCode,WNOHANG));  }    if(m_bAutoDelete){    delete this;  }}#endifvoid CSubprocess::Output (LPCTSTR psz){  m_pfnLogfunc(m_pLogparam,psz);}void CSubprocess::Send(LPCTSTR str){  char *psz=String(str).GetCString();  int nToWrite=strlen(psz);  const char *c=psz;  do {#ifdef _WIN32    DWORD dwWritten;    if(!::WriteFile(m_hwPipe,psz,nToWrite,&dwWritten,0)){      break;    }#else    int dwWritten = write(m_tty, c, nToWrite);    if(-1==dwWritten){      break;    } #endif    nToWrite-=(int)dwWritten;    c+=(int)dwWritten;  } while (nToWrite>0);  //::FlushFileBuffers(m_hwPipe);  delete [] psz;}bool CSubprocess::Kill(bool bRecurse){TRACE(_T("CSubprocess::Kill pid %d recurse=%d\n"),m_idProcess,bRecurse);  PInfoArray arPinfo;  bool rc=false;  if(m_idProcess && -1!=m_idProcess){    // Start of with the easy one:    if(bRecurse) {      // Need to gather this information before we orphan our grandchildren:      PSExtract(arPinfo);    }    #ifdef _WIN32    if(m_hProcess){      TRACE(_T("Terminate process %s\n"),(LPCTSTR)Name(m_idProcess));      rc=(TRUE==::TerminateProcess(m_hProcess,PROCESS_KILL_EXIT_CODE));      // dtor's (or subsequent Run's) responsibility to close the handle    }#else    rc=(0==kill(m_idProcess,SIGTERM));    int status;    waitpid(m_idProcess,&status,WNOHANG);#endif        if(bRecurse) {      // kill process *and* its children      // FIXME: needs to be top-down      for(int i=0;i<(signed)arPinfo.size();i++){        if(arPinfo[i].IsChildOf(m_idProcess)){      #ifdef _WIN32          // begin hack          const String strName(Name(arPinfo[i].PID));          if(_tcsstr(strName,_T("eCosTest")) || _tcsstr(strName,_T("cmd.EXE")) || _tcsstr(strName,_T("CMD.EXE")) || arPinfo[i].PID==(signed)GetCurrentProcessId()){            continue;          }          // end hack          HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID);          if(hProcess){            TRACE(_T("Terminate process %s\n"),(LPCTSTR)Name(arPinfo[i].PID));            rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE));            CloseHandle(hProcess);          } else {            rc=false;          }#else          rc&=(0==kill(arPinfo[i].PID,SIGTERM));          int status;          waitpid(arPinfo[i].PID,&status,WNOHANG);#endif        }      }    }  }  return rc;}Time CSubprocess::CpuTime(bool bRecurse) const{  Time t=0;  // kill process *and* its children  // FIXME: needs to be top-down  #ifdef _WIN32  __int64 ftCreation,ftExit,ftKernel,ftUser;  if(m_hProcess && ::GetProcessTimes (m_hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){    t+=Time((ftKernel+ftUser)/10000);  }  if(bRecurse){    PInfoArray arPinfo;    PSExtract(arPinfo);    if(m_idProcess && -1!=m_idProcess){      for(int i=0;i<(signed)arPinfo.size();i++){        if(arPinfo[i].IsChildOf(m_idProcess)){          t+=arPinfo[i].tCpu;        }      }    }  }#else  PInfoArray arPinfo;  PSExtract(arPinfo);  for(int i=0;i<(signed)arPinfo.size();i++){    if(arPinfo[i].PID==m_idProcess || arPinfo[i].IsChildOf(m_idProcess)){      t+=arPinfo[i].tCpu;    }  }#endif  return t;}#ifdef _WIN32bool CSubprocess::PSExtract(CSubprocess::PInfoArray &arPinfo){  bool rc=false;  arPinfo.clear();  // If Windows NT:  switch(GetPlatform()) {  case VER_PLATFORM_WIN32_NT:    if(hInstLib1) {            // Get procedure addresses.      static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( hInstLib1, "EnumProcesses" ) ;      if( lpfEnumProcesses) {                if(hInstLib2) {                    static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) =            (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( hInstLib2,"NtQueryInformationProcess" ) ;                    if(lpfNtQueryInformationProcess){            DWORD dwMaxPids=256;            DWORD dwPidSize;            DWORD *arPids = NULL ;            do {              delete [] arPids;              arPids=new DWORD[dwMaxPids];            } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ;                        if(dwPidSize/sizeof(DWORD)<dwMaxPids){              rc=true;              for( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) {                // Regardless of OpenProcess success or failure, we                // still call the enum func with the ProcID.                DWORD pid=arPids[dwIndex];                HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid );                 if (hProcess ) {                  struct {                    DWORD ExitStatus; // receives process termination status                    DWORD PebBaseAddress; // receives process environment block address                    DWORD AffinityMask; // receives process affinity mask                    DWORD BasePriority; // receives process priority class                    ULONG UniqueProcessId; // receives process identifier                    ULONG InheritedFromUniqueProcessId; // receives parent process identifier                  } pbi;                  memset( &pbi, 0, sizeof(pbi));                   DWORD retLen;                   __int64 ftCreation,ftExit,ftKernel,ftUser;                  if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 &&                    TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){                    // The second test is important.  It excludes orphaned processes who appear to have been adopted by virtue of a new                    // process having been created with the same ID as their original parent.                    PInfo p;                    p.PID=pid;                    p.PPID=pbi.InheritedFromUniqueProcessId;                    p.tCreation=ftCreation;                    p.tCpu=Time((ftKernel+ftUser)/10000);                    arPinfo.push_back(p);                  }                                    CloseHandle(hProcess);                 }              }            }            delete [] arPids;          }                  }      }          }    break;  case VER_PLATFORM_WIN32_WINDOWS:        if( hInstLib1) {            static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)=        (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( hInstLib1,"CreateToolhelp32Snapshot" ) ;      static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)=        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32First" ) ;      static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)=        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32Next" ) ;      if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) {                // Get a handle to a Toolhelp snapshot of the systems        // processes.        HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;        if(INVALID_HANDLE_VALUE != hSnapShot) {          // Get the first process' information.          PROCESSENTRY32 procentry;          procentry.dwSize = sizeof(PROCESSENTRY32) ;          if(lpfProcess32First( hSnapShot, &procentry )){            rc=true;            do {              PInfo p;              p.PID=procentry.th32ProcessID;              p.PPID=procentry.th32ParentProcessID;              arPinfo.push_back(p);            } while(lpfProcess32Next( hSnapShot, &procentry ));          }          CloseHandle(hSnapShot);        }      }    }    break;  default:    break;  }      SetParents(arPinfo);  if(!rc){    ERROR(_T("Couldn't get process information!\n"));  }  return rc;}#else // UNIXbool CSubprocess::PSExtract(CSubprocess::PInfoArray &arPinfo){  arPinfo.clear();  int i;  FILE *f=popen("ps -l",_T("r") MODE_TEXT);  if(f){    char buf[100];    while(fgets(buf,sizeof(buf)-1,f)){      TCHAR discard[100];      PInfo p;      // Output is in the form      //  F S   UID   PID  PPID  C PRI  NI ADDR    SZ WCHAN  TTY          TIME CMD      //100 S   490   877   876  0  70   0    -   368 wait4  pts/0    00:00:00 bash      int F,UID,C,PRI,NI,SZ,HH,MM,SS;       bool rc=(15==_stscanf(buf,_T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&p.PID,&p.PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS));      if(rc){        p.tCpu=1000*(SS+60*(60*HH+MM));        arPinfo.push_back(p);      }    }    pclose(f);    for(i=0;i<(signed)arPinfo.size();i++){      int pid=arPinfo[i].PPID;      arPinfo[i].pParent=0;      for(int j=0;j<(signed)arPinfo.size();j++){        if(i!=j && arPinfo[j].PID==pid){          arPinfo[i].pParent=&arPinfo[j];          break;        }      }    }  } else {    ERROR(_T("Failed to run ps -l\n"));  }  return true; //FIXME}#endifvoid CSubprocess::SetParents(CSubprocess::PInfoArray &arPinfo){  int i;  for(i=0;i<(signed)arPinfo.size();i++){    PInfo &p=arPinfo[i];    p.pParent=0;    for(int j=0;j<(signed)arPinfo.size();j++){      if(arPinfo[j].PID==p.PPID #ifdef _WIN32        && arPinfo[j].tCreation<p.tCreation#endif        )      {        arPinfo[i].pParent=&arPinfo[j];        break;      }    }  }  // Check for circularity  bool bCircularity=false;  for(i=0;i<(signed)arPinfo.size();i++){    PInfo *p=&arPinfo[i];    for(int j=0;j<(signed)arPinfo.size() && p;j++){      p=p->pParent;    }    // If all is well, p should be NULL here.  Otherwise we have a loop.    if(p){      // Make sure it can't foul things up:      arPinfo[i].pParent=0;      bCircularity=true;    }  }    if(bCircularity){    ERROR(_T("!!! Circularly linked process list at index %d\n"),i);    for(int k=0;k<(signed)arPinfo.size();k++){      const PInfo &p=arPinfo[k];      ERROR(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID);    }  }}bool CSubprocess::PInfo::IsChildOf(int pid) const{  for(PInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage    if(p->PID==pid){      return true;    }  }  return false;}const String CSubprocess::Name(int pid){  String str(String::SFormat(_T("id=%d"),pid));#ifdef _DEBUG#ifdef _WIN32  if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){    static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) =      (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib1,"EnumProcessModules" ) ;    static DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE, LPTSTR, DWORD )=      (DWORD (WINAPI *)(HANDLE, HMODULE,LPTSTR, DWORD )) GetProcAddress( hInstLib1,"GetModuleFileNameExA" ) ;    if( lpfEnumProcessModules &&  lpfGetModuleFileNameEx ) {      HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,pid);      if(hProcess) {        HMODULE hMod;        DWORD dwSize;        if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){          // Get Full pathname:          TCHAR buf[1+MAX_PATH];          lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH);          str+=_TCHAR(' ');          str+=buf;        }        CloseHandle(hProcess);      }    }  }#endif#endif  return str;}#ifdef _WIN32DWORD CSubprocess::GetPlatform(){  OSVERSIONINFO  osver;  osver.dwOSVersionInfoSize = sizeof( osver ) ;  return GetVersionEx( &osver ) ? osver.dwPlatformId : (DWORD)-1;}#endifbool CSubprocess::ProcessAlive(){  return !m_bThreadTerminated;}void CSubprocess::CloseInput(){#ifdef _WIN32  CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE;#else  close(m_tty);#endif}bool CSubprocess::Wait(Duration dTimeout){  return CeCosThreadUtils::WaitFor(m_bThreadTerminated,dTimeout);}const String CSubprocess::ErrorString() const{#ifdef _WIN32  TCHAR *pszMsg;  FormatMessage(      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,    NULL,    m_nErr,    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language    (LPTSTR)&pszMsg,    0,    NULL     );  return pszMsg;#else   return strerror(errno);#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -