diff --git a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp index 5b11ac74612e50015d9efafc4af522bac7181cc2..746c0ef761182c614533c5922ab8a9f30b8b5ef5 100644 --- a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp +++ b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp @@ -116,126 +116,106 @@ MPRPipelineResults MeasurementProvisioner::runPipeline ( const MPPipeline & pipe MPRPipelineResults pipelineResults { }; - try { - - for ( MPPipeline::const_iterator mppcIter = pipeline.cbegin ( ); mppcIter != pipeline.cend ( ); ++mppcIter ) { - if ( mppcIter == pipeline.cbegin ( ) ) { - dup ( inputTmpfileFd ); - dup ( outputTmpfileFd ); - dup ( errorTmpfileFd ); - } else { - // swap stdin and stdout for next command - close ( 0 ); - close ( 1 ); - dup ( outputTmpfileFd ); - dup ( inputTmpfileFd ); - - // rewind previous stdout to the beginning, so the next command can read the whole file as input - lseek ( 0, 0, SEEK_SET ); - - // destroy the contents of previous stdin and rewind to the beginning - lseek ( 1, 0, SEEK_SET ); - ftruncate ( 1, 0 ); - } - - string command = mppcIter->substitute ( substitutionMap ); - - ofdlog << "| \t" << mppcIter->getRawCommand ( ) << flush; + auto fdCleanupLambda = [&] ( ) { + // close tmp files, which results in their deletion + if ( measurementsFd != measurementsTmpfileFd ) + close ( measurementsFd ); + + MPUtils::closeShmFile ( measurementsTmpfile.second ); + MPUtils::closeShmFile ( inputTmpfile.second ); + MPUtils::closeShmFile ( outputTmpfile.second ); + MPUtils::closeShmFile ( errorTmpfile.second ); + + // restore our main stdin, stdout, stderr + close ( 0 ); + close ( 1 ); + close ( 2 ); + + dup ( curStdinFd ); + dup ( curStdoutFd ); + dup ( curStderrFd ); + + close ( curStdinFd ); + close ( curStdoutFd ); + close ( curStderrFd ); + }; + try { - // leave the execution to the system shell - int status = system ( command.c_str ( ) ); + for ( MPPipeline::const_iterator mppcIter = pipeline.cbegin ( ); mppcIter != pipeline.cend ( ); ++mppcIter ) { + if ( mppcIter == pipeline.cbegin ( ) ) { + dup ( inputTmpfileFd ); + dup ( outputTmpfileFd ); + dup ( errorTmpfileFd ); + } else { + // swap stdin and stdout for next command + close ( 0 ); + close ( 1 ); + dup ( outputTmpfileFd ); + dup ( inputTmpfileFd ); - if ( WEXITSTATUS ( status ) != 0 ) { - // rewind stderr to read the error message - lseek ( 2, 0, SEEK_SET ); - ifdstream errfds ( 2 ); + // rewind previous stdout to the beginning, so the next command can read the whole file as input + lseek ( 0, 0, SEEK_SET ); - // read the whole stderr - stringstream buffer; - buffer << errfds.rdbuf ( ); + // destroy the contents of previous stdin and rewind to the beginning + lseek ( 1, 0, SEEK_SET ); + ftruncate ( 1, 0 ); + } - pipelineResults.pipelineStatus.exitCode = WEXITSTATUS ( status ); - pipelineResults.pipelineStatus.errorOrigin = mppcIter->getRawCommand ( ); - pipelineResults.pipelineStatus.errorValue = buffer.str ( ); + string command = mppcIter->substitute ( substitutionMap ); - // destroy stderr contents - lseek ( 2, 0, SEEK_SET ); - ftruncate ( 2, 0 ); + ofdlog << "| \t" << mppcIter->getRawCommand ( ) << flush; - ofdlog << " ERROR!" << endl; - break; - } + // leave the execution to the system shell + int status = system ( command.c_str ( ) ); + if ( WEXITSTATUS ( status ) != 0 ) { + // rewind stderr to read the error message + lseek ( 2, 0, SEEK_SET ); + ifdstream errfds ( 2 ); - if ( mppcIter->getMeasure ( ) ) { - // since we are at the end of file after the output, we need to rewind - lseek ( measurementsFd, 0, SEEK_SET ); + // read the whole stderr + stringstream buffer; + buffer << errfds.rdbuf ( ); - ifdstream ifd ( measurementsFd ); + pipelineResults.pipelineStatus.exitCode = WEXITSTATUS ( status ); + pipelineResults.pipelineStatus.errorOrigin = mppcIter->getRawCommand ( ); + pipelineResults.pipelineStatus.errorValue = buffer.str ( ); - deque < sax::Token > tokens; - sax::SaxParseInterface::parseStream ( ifd, tokens ); + // destroy stderr contents + lseek ( 2, 0, SEEK_SET ); + ftruncate ( 2, 0 ); - measurements::MeasurementResults measurementResults = measurements::MeasurementResultsXml::parse ( tokens ); + ofdlog << " ERROR!" << endl; + break; + } - pipelineResults.commandResults.push_back ( { mppcIter->getRawCommand ( ), std::move ( measurementResults ) } ); + if ( mppcIter->getMeasure ( ) ) { + // since we are at the end of file after the output, we need to rewind + lseek ( measurementsFd, 0, SEEK_SET ); - // destroy the contents and rewind for another commands measurements - lseek ( measurementsFd, 0, SEEK_SET ); - ftruncate ( measurementsFd, 0 ); - } - - ofdlog << " OK!" << endl; - } + ifdstream ifd ( measurementsFd ); - } catch(::exception::CommonException & ce) { - // close tmp files, which results in their deletion - if ( measurementsFd != measurementsTmpfileFd ) - close ( measurementsFd ); + deque < sax::Token > tokens; + sax::SaxParseInterface::parseStream ( ifd, tokens ); - //MPUtils::closeShmFile ( measurementsTmpfile.second ); - //MPUtils::closeShmFile ( inputTmpfile.second ); - //MPUtils::closeShmFile ( outputTmpfile.second ); - //MPUtils::closeShmFile ( errorTmpfile.second ); + measurements::MeasurementResults measurementResults = measurements::MeasurementResultsXml::parse ( tokens ); - // restore our main stdin, stdout, stderr - close ( 0 ); - close ( 1 ); - close ( 2 ); + pipelineResults.commandResults.push_back ( { mppcIter->getRawCommand ( ), std::move ( measurementResults ) } ); - dup ( curStdinFd ); - dup ( curStdoutFd ); - dup ( curStderrFd ); - - close ( curStdinFd ); - close ( curStdoutFd ); - close ( curStderrFd ); + // destroy the contents and rewind for another commands measurements + lseek ( measurementsFd, 0, SEEK_SET ); + ftruncate ( measurementsFd, 0 ); + } + ofdlog << " OK!" << endl; + } + } catch ( ::exception::CommonException & ce ) { + fdCleanupLambda ( ); throw ce; } - // close tmp files, which results in their deletion - if ( measurementsFd != measurementsTmpfileFd ) - close ( measurementsFd ); - - MPUtils::closeShmFile ( measurementsTmpfile.second ); - MPUtils::closeShmFile ( inputTmpfile.second ); - MPUtils::closeShmFile ( outputTmpfile.second ); - MPUtils::closeShmFile ( errorTmpfile.second ); - - // restore our main stdin, stdout, stderr - close ( 0 ); - close ( 1 ); - close ( 2 ); - - dup ( curStdinFd ); - dup ( curStdoutFd ); - dup ( curStderrFd ); - - close ( curStdinFd ); - close ( curStdoutFd ); - close ( curStderrFd ); + fdCleanupLambda ( ); return pipelineResults; } diff --git a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp index f16c227ccdb5de00957631665f92879a6ca6b47c..30e643cd2ac4b7b3df35acab91a39301c966cfdf 100644 --- a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp +++ b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp @@ -47,6 +47,11 @@ MPUtils::ShmFileHandle MPUtils::openShmFile ( ) { if ( shmFd == -1 ) throw::exception::CommonException ( "MPUtils: shm_open failed" ); + // turn off FD_CLOEXEC, so it survives call to system() (exec()) + int fl = fcntl ( shmFd, F_GETFD ); + fl &= ~FD_CLOEXEC; + fcntl ( shmFd, F_SETFD, fl ); + filename = "/dev/shm" + filename; if ( access ( filename.c_str ( ), F_OK ) == -1 ) {