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

📄 subprocess.cpp

📁 eCos1.31版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//####COPYRIGHTBEGIN####//                                                                          // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.//// ----------------------------------------------------------------------------//                                                                          //####COPYRIGHTEND####//===========================================================================//===========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): 	sdf// Contact(s):	sdf// Date:		1998/08/11// Version:		0.01// Purpose:	// Description:	This is the implementation of the class which allows for spawning subprocesses//// Requires:	// Provides:	// See also:    // Known bugs:	// Usage:	////####DESCRIPTIONEND####////===========================================================================#include "subprocess.h"const UINT CSubprocess::PROCESS_KILL_EXIT_CODE=0xCCFFCCFF;CSubprocess::CSubprocess(bool bVerbose):  m_dwParentThreadId(0),  m_pstrOutput(0),  m_idProcess(0),  m_bThreadRunning(false),  m_bVerbose(bVerbose),  m_dwExitCode(0xffffffff),  m_bAutoDelete(false),  m_hThread(0),  m_pfnLogfunc(0),  m_pLogparam(0),  m_hwndParent(0){}// Run (non-blocking and discarding output)/* static */ unsigned int CSubprocess::Run(LPCTSTR pszCmd,LPCTSTR pszDir){  CSubprocess *psp=new CSubprocess(false);  psp->m_bAutoDelete=true;  String strOutput;  return psp->Run(strOutput,pszCmd,pszDir);}unsigned int CSubprocess::Run(LogFunc *pfnLog,void * pLogparam, LPCTSTR pszCmd,LPCTSTR pszDir){  unsigned int rc;  if(m_bThreadRunning){    rc=0;  } else {    m_pfnLogfunc=pfnLog;    m_pLogparam=pLogparam;    m_strCmd=pszCmd;    m_strDir=pszDir;    rc=CreateProcess();    if(rc){      ThreadFunc();    }  }  return rc;}#ifdef _WIN32// Non-blocking: WM_SUBPROCESS messages are posted to HWND supplied as argumentunsigned int CSubprocess::Run(HWND hwndParent,LPCTSTR pszCmd,LPCTSTR pszDir){  unsigned int rc;  if(m_bThreadRunning){    rc=0;  } else {    m_hwndParent=hwndParent;    m_strCmd=pszCmd;    m_strDir=pszDir;    rc=CreateProcess();    if(rc){      DWORD dwID;      m_bThreadRunning=true;      m_hThread=::CreateThread(NULL,0,ThreadFunc,this,0,&dwID);    }  }  return rc;}// Non-blocking: WM_SUBPROCESS messages are posted to thread supplied as argumentunsigned int CSubprocess::Run(DWORD dwParentThreadId,LPCTSTR pszCmd,LPCTSTR pszDir){  unsigned int rc;  if(m_bThreadRunning){    rc=0;  } else {    m_dwParentThreadId=dwParentThreadId;    m_strCmd=pszCmd;    m_strDir=pszDir;    rc=CreateProcess();    if(rc){      DWORD dwID;      m_bThreadRunning=true;      m_hThread=::CreateThread(NULL,0,ThreadFunc,this,0,&dwID);    }  }  return rc;}#endif// Blocking: output is placed in string supplied as argumentunsigned int CSubprocess::Run(String &strOutput,LPCTSTR pszCmd,LPCTSTR pszDir){  strOutput=_T("");  m_strCmd=pszCmd;  m_strDir=pszDir;  m_pstrOutput=&strOutput;  unsigned int rc=CreateProcess();  if(rc){    ThreadFunc();  }  return rc;}CSubprocess::~CSubprocess(){  Kill();    if(m_hThread){ // running non-blocking and thread started (but possibly already finished)    if(WAIT_TIMEOUT==WaitForSingleObject(m_hThread,1000)){      // In general this is bad news, but we can't allow the thread to live on if      // the class object is about to be deleted.      if(m_bVerbose){        Output(_T("*** CSubprocess: Forcibly terminating thread\n"));      }      ::TerminateThread(m_hThread,0);    }    ::CloseHandle(m_hThread);  }}#ifdef _WIN32unsigned int CSubprocess::CreateProcess(){    STARTUPINFO   si;                    // For CreateProcess call  HANDLE        hrPipe,hwPipe,hwPipe2;  // Create the anonymous pipe    SECURITY_ATTRIBUTES saPipe;          // Security for anonymous pipe  saPipe.nLength = sizeof(SECURITY_ATTRIBUTES);  saPipe.lpSecurityDescriptor = NULL;  saPipe.bInheritHandle = true;    ::CreatePipe(&m_hrPipe,&hwPipe,&saPipe,80);    // In most cases you can get away with using the same anonymous  // pipe write handle for both the child's standard output and  // standard error, but this may cause problems if the child app  // explicitly closes one of its standard output or error handles. If  // that happens, the anonymous pipe will close, since the child's  // standard output and error handles are really the same handle. The  // child won't be able to write to the other write handle since the  // pipe is now gone, and parent reads from the pipe will return  // ERROR_BROKEN_PIPE and child output will be lost. To solve this  // problem, simply duplicate the write end of the pipe to create  // another distinct, separate handle to the write end of the pipe.  // One pipe write handle will serve as standard out, the other as  // standard error. Now *both* write handles must be closed before the  // write end of the pipe actually closes.    ::DuplicateHandle(::GetCurrentProcess(),			// Source process    hwPipe,		        // Handle to duplicate    ::GetCurrentProcess(),   // Destination process    &hwPipe2,	            // New handle, used as stderr by child     0,                     // New access flags - ignored since DUPLICATE_SAME_ACCESS    true,                  // It's inheritable    DUPLICATE_SAME_ACCESS);    ::CreatePipe(&hrPipe,&m_hwPipe,&saPipe,80);    memset(&si, 0, sizeof(si));  si.cb = sizeof(si);    si.hStdOutput = hwPipe;  si.hStdError =  hwPipe2;  si.hStdInput =  hrPipe;  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;  si.wShowWindow = SW_SHOW;    LPCTSTR pszDir=0;  if(m_strDir.GetLength()){    pszDir=m_strDir; // NULL = start in current  }    PROCESS_INFORMATION pi;  unsigned int rc=(::CreateProcess(NULL,    // Application name    m_strCmd.GetBuffer(m_strCmd.GetLength()),  // Full command line for child    NULL,    // Process security descriptor    NULL,    // Thread security descriptor    true,    // Inherit handles? Also use if STARTF_USESTDHANDLES    // Creation flags of     // CREATE_NEW_PROCESS_GROUP so we can use     // GenerateConsoleCtrlEvent to     // terminate the child    DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,    NULL,    // Inherited environment address    pszDir,&si,&pi) ? pi.dwProcessId : 0);    m_strCmd.ReleaseBuffer();  String strMsg;    if(rc){    m_idProcess=pi.dwProcessId;    m_hProcess=pi.hProcess;    strMsg.Format(_T("*** Process %d created \"%s\"\n"),m_idProcess,(LPCTSTR)m_strCmd);    m_dwExitCode=STILL_ACTIVE;  } else {    strMsg.Format(_T("*** Failed to create process \"%s\"\n"),(LPCTSTR)m_strCmd);    m_dwExitCode=GetLastError();  }    if(m_bVerbose){    Output(strMsg);  }    ::CloseHandle(hrPipe);  ::CloseHandle(hwPipe);  ::CloseHandle(hwPipe2);  ::CloseHandle(pi.hThread);    return rc;  }#else // UNIXunsigned int CSubprocess::CreateProcess(){  int pipe_ends_w[2];  if (pipe(pipe_ends_w) < 0 ) {     Log(_T("Failed to create pipe_ends_w - %s\n"),strerror(errno));  } else {    int pipe_ends_r[2];    if (pipe(pipe_ends_r) < 0 ) {       Log(_T("Failed to create pipe_ends_r - %s\n"),strerror(errno));    } else {      int pid=fork();            switch (pid) {        // Fork failed        case -1:

⌨️ 快捷键说明

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