void testCaptureOutput() { OsStatus stat; // this command will produce a mix of stdout and stderr UtlString appName = "ls"; UtlString params[10]; params[0] = "-d"; params[1] = "/madeUpNameDoesNotExist"; params[2] = "."; params[3] = NULL; OsProcess process; OsPath startupDir = "."; // std::cout << "Launching process: " << appName.data() << std::endl; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "launching process %s %s", appName.data(), params[0].data()); stat = process.launch(appName, params, startupDir, OsProcessBase::NormalPriorityClass, false, false/* don't ignore child signals*/); CPPUNIT_ASSERT(stat == OS_SUCCESS); CPPUNIT_ASSERT(process.isRunning()); UtlString stdoutMsg, stderrMsg; int rc; // can't guarantee in what order we'll get the output, just check for both bool bGotStdout = false; bool bGotStderr = false; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "calling getOutput"); while ( (rc = process.getOutput(&stdoutMsg, &stderrMsg)) > 0 ) { if ( stdoutMsg.length() > 0 ) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "got stdout: %s", stdoutMsg.data()); bGotStdout = true; } if ( stderrMsg.length() > 0 ) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "got stderr: %s", stderrMsg.data()); bGotStderr = true; } } CPPUNIT_ASSERT(bGotStdout==true); CPPUNIT_ASSERT(bGotStderr==true); CPPUNIT_ASSERT(rc == 0); // since we forced an invalid command, we expect a non-zero return code rc = process.wait(0); CPPUNIT_ASSERT(rc != 0); }
void testLaunch() { OsStatus stat; UtlString appName = "ping"; UtlString params[10]; params[0] = "127.0.0.1"; #ifdef _WIN32 //need to do this only on win32, linux already does this by default params[1] = "-t"; #endif OsProcess process; UtlString envKey = "TESTKEY1"; UtlString envValue = "TESTVALUE1"; process.setEnv(envKey,envValue); envKey = "TESTKEY2"; envValue ="TESTVALUE2"; process.setEnv(envKey,envValue); envKey = "TESTKEY3"; envValue = "TESTVALUE3"; process.setEnv(envKey,envValue); OsPath startupDir = "."; //std::cout << "Launching process: " << appName.data() << std::endl; stat = process.launch(appName,params,startupDir); CPPUNIT_ASSERT_MESSAGE("Launched application", stat == OS_SUCCESS); CPPUNIT_ASSERT_MESSAGE("Application running", process.isRunning()); int priority; process.setPriority(1); process.getPriority(priority); KNOWN_BUG("INTERMITTENT on F8 with 64Bit changes", "XECS-480"); CPPUNIT_ASSERT_MESSAGE("Set priority ok", priority == 1); OsProcess newProcess; stat = OsProcess::getByPID(process.getPID(), newProcess); CPPUNIT_ASSERT_MESSAGE("Got process pid ok", stat == OS_SUCCESS); //std::cout << "Waiting 5 secs before killing process..." << std::endl; OsTask::delay(5000); stat = newProcess.kill(); CPPUNIT_ASSERT_MESSAGE("Able to kill process", stat == OS_SUCCESS); }
OsStatus TestProcessClass() { OsStatus retval = OS_FAILED; cout << "Starting Process Class Method Test...\n"; //try to launch dir UtlString appName = "ping"; UtlString params[10]; params[0] = "127.0.0.1"; #ifdef _WIN32 //need to do this only on win32, linux already does this by default params[1] = "-t"; #endif //try and launch IE UtlString envKey = "TESTKEY1"; UtlString envValue = "TESTVALUE1"; process.setEnv(envKey,envValue); envKey = "TESTKEY2"; envValue ="TESTVALUE2"; process.setEnv(envKey,envValue); envKey = "TESTKEY3"; envValue = "TESTVALUE3"; process.setEnv(envKey,envValue); OsPath startupDir = "."; cout << "Launching process: " << appName.data() << endl; if (process.launch(appName,params,startupDir) == OS_SUCCESS) { if (process.isRunning()) { cout << "Successful launch. " << endl; //try to set the prio to 1 int prio; process.getPriority(prio); cout << "Current priority = " << prio << endl; process.setPriority(1); process.getPriority(prio); cout << "New priority (should say 1) = " << prio << endl; OsProcess newProcess; //see if we can get the process we started by pid if (OsProcess::getByPID(process.getPID(),newProcess) == OS_SUCCESS) { //wait a bit cout << "Waiting 5 secs before killing process..." << endl; OsTask::delay(5000); //ok, now kill that bad boy... if (newProcess.kill() == OS_SUCCESS) cout << "Killed\n"; else cout << "ERROR: Could not kill process!\n"; retval = OS_SUCCESS; } } else cout << "ERROR: Process says it's not running!\n"; } else { cout << "ERROR: Could not create process " << appName.data() << endl; } cout << "DONE Process Class Method Test.\n"; return retval; }
bool ZoneAdminRpcExec::execute(const HttpRequestContext& requestContext, UtlSList& params, void* userData, XmlRpcResponse& response, ExecutionStatus& status) { bool result = false; status = XmlRpcMethod::FAILED; if (2 != params.entries()) { handleExtraExecuteParam(name(), response, status); } else { if (!params.at(0) || !params.at(0)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_CALLING_HOST, response, status); } else { if (!params.at(1) || !params.at(1)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_COMMAND, response, status); } else { UtlString* pCallingHostname = dynamic_cast<UtlString*>(params.at(0)); SipxRpc* pSipxRpcImpl = ((SipxRpc *)userData); if(validCaller(requestContext, *pCallingHostname, response, *pSipxRpcImpl, name())) { UtlBool method_result(true); UtlString arguments[3]; OsPath mWorkingDirectory = "."; OsPath mExec = SipXecsService::Path(SipXecsService::LibExecDirType,"sipxzoneadmin"); UtlString mStdOutFile; UtlString mStdErrFile; UtlString* pSubCommand = dynamic_cast<UtlString*>(params.at(1)); if ( !buildOutputFiles(*pSubCommand, mStdOutFile, mStdErrFile)) { // Invalid request. Set a Fault. response.setFault(ZoneAdminRpcMethod::FailureToLaunch, "Invalid command"); status = XmlRpcMethod::FAILED; return result; } OsPath mStdOutPath = SipXecsService::Path(SipXecsService::LogDirType, mStdOutFile.data()); OsPath mStdErrPath = SipXecsService::Path(SipXecsService::LogDirType, mStdErrFile.data()); // Pass the argumenst to sipx-zoneadmin.sh arguments[0] = "-n"; // non-interactive arguments[1] = pSubCommand->data(); // string "<primary server> -o <secondary server>" // Make sure that there is no other instance running. if (! duplicateProcess(ZoneAdminExec, response, status)) { // execute the command and return whether or not the launch was successful. OsProcess* zoneCheck = new OsProcess(); // Setup the Standard Output and Standard Error files. OsPath mStdInFile; // Blank int rc; rc = zoneCheck->setIORedirect(mStdInFile, mStdOutPath, mStdErrPath); // Launch the process but tell the parent to ignore the child's signals (especially on shutdown). // It will let the system handle it to avoid a defunct process. if ( (rc=zoneCheck->launch(mExec, &arguments[0], mWorkingDirectory, zoneCheck->NormalPriorityClass, FALSE, TRUE)) // Parent to ignore child signals. == OS_SUCCESS ) { // Construct and set the response. UtlSList outputPaths; outputPaths.insert(&mStdOutPath); outputPaths.insert(&mStdErrPath); // Add the file resources to Supervisor Process so they can be retrieved FileResource::logFileResource( mStdOutPath, SipxProcessManager::getInstance()->findProcess(SUPERVISOR_PROCESS_NAME)); FileResource::logFileResource( mStdErrPath, SipxProcessManager::getInstance()->findProcess(SUPERVISOR_PROCESS_NAME)); response.setResponse(&outputPaths); status = XmlRpcMethod::OK; result = true; } // launch else { // Failed to launch the command, send a fault. response.setFault(ZoneAdminRpcMethod::FailureToLaunch, "Failure to launch command"); status = XmlRpcMethod::FAILED; } delete zoneCheck; } // duplicateProcess } // validcaller else { status = XmlRpcMethod::FAILED; } } // param 1 okay } // param 0 okay } //number of parms check return result; }
bool SwAdminRpcSnapshot::execute(const HttpRequestContext& requestContext, UtlSList& params, void* userData, XmlRpcResponse& response, ExecutionStatus& status) { bool result = false; status = XmlRpcMethod::FAILED; if (2 != params.entries()) { handleExtraExecuteParam(name(), response, status); } else { if (!params.at(0) || !params.at(0)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_CALLING_HOST, response, status); } else { UtlString* pCallingHostname = dynamic_cast<UtlString*>(params.at(0)); SipxRpc* pSipxRpcImpl = ((SipxRpc *)userData); if (!params.at(1) || !params.at(1)->isInstanceOf(UtlSList::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_COMMAND, response, status); } else { if (validCaller(requestContext, *pCallingHostname, response, *pSipxRpcImpl, name())) { UtlSList* pArgsList = dynamic_cast<UtlSList*>(params.at(1)); UtlSListIterator argsListIterator( *pArgsList ); UtlString * pArg; // Make sure that there is no other instance running. if (! duplicateProcess(SwAdminSnapshot, response, status)) { UtlBool method_result(true); UtlString arguments[pArgsList->entries()+2]; UtlString subCommand; OsPath mWorkingDirectory = "."; OsPath mExec = SipXecsService::Path(SipXecsService::BinDirType, SwAdminSnapshot); UtlString mStdOutFile(SwAdminSnapshot_cmd); UtlString mStdErrFile(SwAdminSnapshot_cmd); mStdOutFile.append(SwAdminStdOut_filetype); mStdErrFile.append(SwAdminStdErr_filetype); // Construct and set the response. OsPath mStdOutPath = OsPath(SipXecsService::Path(SipXecsService::LogDirType, mStdOutFile.data())); OsPath mStdErrPath = OsPath(SipXecsService::Path(SipXecsService::LogDirType, mStdErrFile.data())); OsPath processOutPath = OsPath(SipXecsService::Path(SipXecsService::TmpDirType, OUTPUT_FILENAME)); for (int i = 0; (pArg = dynamic_cast<UtlString*>(argsListIterator())); i++) { XmlUnEscape(arguments[i], *pArg); } arguments[pArgsList->entries()] = processOutPath.data(); arguments[pArgsList->entries()+1] = NULL; // execute the command and return whether or not the launch was successful. OsProcess* swCheck = new OsProcess(); // Setup the Standard Output and Standard Error files. OsPath mStdInFile; // Blank int rc; rc = swCheck->setIORedirect(mStdInFile, mStdOutPath, mStdErrPath); // Launch the process but tell the parent to ignore the child's signals (especially on shutdown). // It will let the system handle it to avoid a defunct process. if ( (rc=swCheck->launch(mExec, &arguments[0], mWorkingDirectory, swCheck->NormalPriorityClass, FALSE, TRUE)) // Parent to ignore child signals. == OS_SUCCESS ) { // Add the file resources to Supervisor Process so they can be retrieved FileResource::logFileResource( mStdOutPath, SipxProcessManager::getInstance()->findProcess(SUPERVISOR_PROCESS_NAME)); FileResource::logFileResource( mStdErrPath, SipxProcessManager::getInstance()->findProcess(SUPERVISOR_PROCESS_NAME)); FileResource::logFileResource( processOutPath, SipxProcessManager::getInstance()->findProcess(SUPERVISOR_PROCESS_NAME)); UtlString outputFilename = processOutPath; // Construct and set the response. UtlSList outputPaths; outputPaths.insert(&outputFilename); outputPaths.insert(&mStdOutPath); outputPaths.insert(&mStdErrPath); response.setResponse(&outputPaths); status = XmlRpcMethod::OK; result = true; } // launch else { // Failed to launch the command, send a fault. response.setFault(SwAdminRpcMethod::FailureToLaunch, "Failure to launch command"); status = XmlRpcMethod::FAILED; } delete swCheck; } // duplicateProcess } // validcaller else { status = XmlRpcMethod::FAILED; } } // param 1 okay } // param 0 okay } //number of parms check return result; }
void testSendInput() { OsStatus stat; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "testSendInput"); // this command will produce a mix of stdout and stderr UtlString appName = "sh"; UtlString params[10]; params[0] = "-c"; params[1] = "cat"; params[2] = NULL; OsProcess process; OsPath startupDir = "."; // std::cout << "Launching process: " << appName.data() << std::endl; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "launching process %s %s", appName.data(), params[0].data()); stat = process.launch(appName, params, startupDir, OsProcessBase::NormalPriorityClass, false, false/* don't ignore child signals*/); CPPUNIT_ASSERT(stat == OS_SUCCESS); CPPUNIT_ASSERT(process.isRunning()); UtlString stdoutMsg, stderrMsg; int rc; // send "well", then "hello", and expect "goodbye" back bool bGotGoodbye = false; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "starting sendInput task"); SimpleTask * pTask = new SimpleTask(&process); pTask->start(); OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "calling getOutput"); while ( !bGotGoodbye && pTask->isStarted() && (rc = process.getOutput(&stdoutMsg, &stderrMsg)) > 0 ) { if ( stdoutMsg.length() > 0 ) { // The output is sure to contain newlines, and may contain several lines. // Clean it up before dispatching. UtlTokenizer tokenizer(stdoutMsg); UtlString msg; while ( tokenizer.next(msg, "\r\n") ) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "got stdout: %s", msg.data()); if ( msg == "goodbye" ) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "got goodbye command"); bGotGoodbye = true; } } } if ( stderrMsg.length() > 0 ) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "got stderr: %s", stderrMsg.data()); } } CPPUNIT_ASSERT(bGotGoodbye==true); pTask->requestShutdown(); delete pTask; }