bool CServerSession::OnRunImage( CNcpMessage* pMsg, int nSize ) { char path[MAXPATH]; //parse the parameters bool bSync = (bool)pMsg->GetRet(); string strImageName = (char*)(pMsg->GetData()); if( !IsAbsDir( strImageName.c_str() ) ){ strcpy( path, m_strCurDir.c_str() ); CatDir( path, strImageName.c_str(), path, ELEMENTS(path) ); }else{ strcpy( path, strImageName.c_str() ); } BOOL bOk; int nPriority = m_pServApp->GetPriority(); if( bSync ){ //synchronize running, register the handle and wait the process HPROCESS hProcess; bOk = CreateProcess( path, m_strCurDir.c_str(), nPriority, &hProcess ); m_pServApp->RegistProc( hProcess ); WaitProcess( hProcess ); m_pServApp->UnregistProc( hProcess ); CloseProcessHandle( hProcess ); }else{ //just run the process and return. bOk = CreateProcess( path, m_strCurDir.c_str(), nPriority, NULL ); } //send back the return code. pMsg->Init( CM_ACK ); if( !bOk ){ pMsg->SetRet( E_NOEXEC ); } pMsg->Send( m_sock ); return bOk; }
int ScriptController::Execute() { PrepareEnvOptions(nullptr); PrepareArgs(); m_completed = false; int exitCode = 0; #ifdef CHILD_WATCHDOG bool childConfirmed = false; while (!childConfirmed && !m_terminated) { #endif int pipein = -1, pipeout = -1; StartProcess(&pipein, &pipeout); if (pipein == -1) { m_completed = true; return -1; } // open the read end m_readpipe = fdopen(pipein, "r"); if (!m_readpipe) { PrintMessage(Message::mkError, "Could not open read pipe to %s", *m_infoName); close(pipein); close(pipeout); m_completed = true; return -1; } m_writepipe = 0; if (m_needWrite) { // open the write end m_writepipe = fdopen(pipeout, "w"); if (!m_writepipe) { PrintMessage(Message::mkError, "Could not open write pipe to %s", *m_infoName); close(pipein); close(pipeout); m_completed = true; return -1; } } #ifdef CHILD_WATCHDOG debug("Creating child watchdog"); ChildWatchDog watchDog; watchDog.SetAutoDestroy(false); watchDog.SetProcessId(m_processId); watchDog.SetInfoName(m_infoName); watchDog.Start(); #endif CharBuffer buf(1024 * 10); debug("Entering pipe-loop"); bool firstLine = true; bool startError = false; while (!m_terminated && !m_detached && !feof(m_readpipe)) { if (ReadLine(buf, buf.Size(), m_readpipe) && m_readpipe) { #ifdef CHILD_WATCHDOG if (!childConfirmed) { childConfirmed = true; watchDog.Stop(); debug("Child confirmed"); continue; } #endif if (firstLine && !strncmp(buf, "[ERROR] Could not start ", 24)) { startError = true; } ProcessOutput(buf); firstLine = false; } } debug("Exited pipe-loop"); #ifdef CHILD_WATCHDOG debug("Destroying WatchDog"); if (!childConfirmed) { watchDog.Stop(); } while (watchDog.IsRunning()) { Util::Sleep(5); } #endif if (m_readpipe) { fclose(m_readpipe); } if (m_writepipe) { fclose(m_writepipe); } if (m_terminated && m_infoName) { warn("Interrupted %s", *m_infoName); } exitCode = 0; if (!m_detached) { exitCode = WaitProcess(); #ifndef WIN32 if (exitCode == FORK_ERROR_EXIT_CODE && startError) { exitCode = -1; } #endif } #ifdef CHILD_WATCHDOG } // while (!bChildConfirmed && !m_bTerminated) #endif debug("Exit code %i", exitCode); m_completed = true; return exitCode; }