cmWorkingDirectory: Check success of current dir changes

This commit is contained in:
Craig Scott 2018-03-04 17:27:09 +11:00
parent e654622aee
commit e60e4dfc88
17 changed files with 227 additions and 19 deletions

View File

@ -9,6 +9,7 @@
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmWorkingDirectory.h" #include "cmWorkingDirectory.h"
#include <cstring>
#include <ostream> #include <ostream>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -51,6 +52,7 @@ int cmCPackArchiveGenerator::InitializeInternal()
this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1"); this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
return this->Superclass::InitializeInternal(); return this->Superclass::InitializeInternal();
} }
int cmCPackArchiveGenerator::addOneComponentToArchive( int cmCPackArchiveGenerator::addOneComponentToArchive(
cmArchiveWrite& archive, cmCPackComponent* component) cmArchiveWrite& archive, cmCPackComponent* component)
{ {
@ -61,6 +63,13 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
localToplevel += "/" + component->Name; localToplevel += "/" + component->Name;
// Change to local toplevel // Change to local toplevel
cmWorkingDirectory workdir(localToplevel); cmWorkingDirectory workdir(localToplevel);
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Failed to change working directory to "
<< localToplevel << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
return 0;
}
std::string filePrefix; std::string filePrefix;
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME"); filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
@ -237,6 +246,13 @@ int cmCPackArchiveGenerator::PackageFiles()
// CASE 3 : NON COMPONENT package. // CASE 3 : NON COMPONENT package.
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive); DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
cmWorkingDirectory workdir(toplevel); cmWorkingDirectory workdir(toplevel);
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Failed to change working directory to "
<< toplevel << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
return 0;
}
for (std::string const& file : files) { for (std::string const& file : files) {
// Get the relative path to the file // Get the relative path to the file
std::string rp = cmSystemTools::RelativePath(toplevel, file); std::string rp = cmSystemTools::RelativePath(toplevel, file);

View File

@ -6,6 +6,7 @@
#include "cmsys/Glob.hxx" #include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include <algorithm> #include <algorithm>
#include <cstring>
#include <memory> // IWYU pragma: keep #include <memory> // IWYU pragma: keep
#include <utility> #include <utility>
@ -404,6 +405,13 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Change dir to: " << goToDir cmCPackLogger(cmCPackLog::LOG_DEBUG, "Change dir to: " << goToDir
<< std::endl); << std::endl);
cmWorkingDirectory workdir(goToDir); cmWorkingDirectory workdir(goToDir);
if (workdir.Failed()) {
cmCPackLogger(
cmCPackLog::LOG_ERROR, "Failed to change working directory to "
<< goToDir << " : " << std::strerror(workdir.GetLastResult())
<< std::endl);
return 0;
}
for (auto const& symlinked : symlinkedFiles) { for (auto const& symlinked : symlinkedFiles) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: " cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: "
<< symlinked.second << "--> " << symlinked.first << symlinked.second << "--> " << symlinked.first

View File

@ -11,6 +11,7 @@
#include "cmsys/Process.h" #include "cmsys/Process.h"
#include <chrono> #include <chrono>
#include <cstring>
#include <ratio> #include <ratio>
#include <stdlib.h> #include <stdlib.h>
@ -196,6 +197,16 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
cmSystemTools::MakeDirectory(this->BinaryDir); cmSystemTools::MakeDirectory(this->BinaryDir);
} }
cmWorkingDirectory workdir(this->BinaryDir); cmWorkingDirectory workdir(this->BinaryDir);
if (workdir.Failed()) {
auto msg = "Failed to change working directory to " + this->BinaryDir +
" : " + std::strerror(workdir.GetLastResult()) + "\n";
if (outstring) {
*outstring = msg;
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE, msg);
}
return 1;
}
if (this->BuildNoCMake) { if (this->BuildNoCMake) {
// Make the generator available for the Build call below. // Make the generator available for the Build call below.
@ -307,7 +318,16 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
// run the test from the this->BuildRunDir if set // run the test from the this->BuildRunDir if set
if (!this->BuildRunDir.empty()) { if (!this->BuildRunDir.empty()) {
out << "Run test in directory: " << this->BuildRunDir << "\n"; out << "Run test in directory: " << this->BuildRunDir << "\n";
cmSystemTools::ChangeDirectory(this->BuildRunDir); if (!workdir.SetDirectory(this->BuildRunDir)) {
out << "Failed to change working directory : "
<< std::strerror(workdir.GetLastResult()) << "\n";
if (outstring) {
*outstring = out.str();
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
}
return 1;
}
} }
out << "Running test command: \"" << fullPath << "\""; out << "Running test command: \"" << fullPath << "\"";
for (std::string const& testCommandArg : this->TestCommandArgs) { for (std::string const& testCommandArg : this->TestCommandArgs) {

View File

@ -23,6 +23,7 @@
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <cstring>
#include <iomanip> #include <iomanip>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
@ -975,7 +976,12 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::string testingDir = this->CTest->GetBinaryDir() + "/Testing"; std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
std::string tempDir = testingDir + "/CoverageInfo"; std::string tempDir = testingDir + "/CoverageInfo";
cmSystemTools::MakeDirectory(tempDir); if (!cmSystemTools::MakeDirectory(tempDir)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to make directory: " << tempDir << std::endl);
cont->Error++;
return 0;
}
cmWorkingDirectory workdir(tempDir); cmWorkingDirectory workdir(tempDir);
int gcovStyle = 0; int gcovStyle = 0;
@ -1376,6 +1382,14 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
this->Quiet); this->Quiet);
std::string fileDir = cmSystemTools::GetFilenamePath(f); std::string fileDir = cmSystemTools::GetFilenamePath(f);
cmWorkingDirectory workdir(fileDir); cmWorkingDirectory workdir(fileDir);
if (workdir.Failed()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to change working directory to "
<< fileDir << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
cont->Error++;
continue;
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Current coverage dir: " << fileDir << std::endl, "Current coverage dir: " << fileDir << std::endl,
@ -1600,6 +1614,12 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
gl.RecurseThroughSymlinksOff(); gl.RecurseThroughSymlinksOff();
std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory"); std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
cmWorkingDirectory workdir(buildDir); cmWorkingDirectory workdir(buildDir);
if (workdir.Failed()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to change working directory to " << buildDir
<< std::endl);
return false;
}
// Run profmerge to merge all *.dyn files into dpi files // Run profmerge to merge all *.dyn files into dpi files
if (!cmSystemTools::RunSingleCommand("profmerge")) { if (!cmSystemTools::RunSingleCommand("profmerge")) {

View File

@ -9,6 +9,7 @@
#include "cmWorkingDirectory.h" #include "cmWorkingDirectory.h"
#include "cmake.h" #include "cmake.h"
#include <cstring>
#include <sstream> #include <sstream>
#include <stdlib.h> #include <stdlib.h>
@ -218,6 +219,21 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
} }
cmWorkingDirectory workdir( cmWorkingDirectory workdir(
this->CTest->GetCTestConfiguration("BuildDirectory")); this->CTest->GetCTestConfiguration("BuildDirectory"));
if (workdir.Failed()) {
this->SetError("failed to change directory to " +
this->CTest->GetCTestConfiguration("BuildDirectory") +
" : " + std::strerror(workdir.GetLastResult()));
if (capureCMakeError) {
this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
"-1");
cmCTestLog(this->CTest, ERROR_MESSAGE, this->GetName()
<< " " << this->GetError() << "\n");
// return success because failure is recorded in CAPTURE_CMAKE_ERROR
return true;
}
return false;
}
int res = handler->ProcessHandler(); int res = handler->ProcessHandler();
if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) { if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
std::ostringstream str; std::ostringstream str;

View File

@ -19,6 +19,7 @@
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <cstring>
#include <iomanip> #include <iomanip>
#include <list> #include <list>
#include <math.h> #include <math.h>
@ -151,14 +152,20 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
} }
} }
cmWorkingDirectory workdir(this->Properties[test]->Directory); // Always lock the resources we'll be using, even if we fail to set the
// working directory because FinishTestProcess() will try to unlock them
// Lock the resources we'll be using
this->LockResources(test); this->LockResources(test);
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
testRun->StartFailure("Failed to change working directory to " +
this->Properties[test]->Directory + " : " +
std::strerror(workdir.GetLastResult()));
} else {
if (testRun->StartTest(this->Total)) { if (testRun->StartTest(this->Total)) {
return true; return true;
} }
}
this->FinishTestProcess(testRun, false); this->FinishTestProcess(testRun, false);
return false; return false;
@ -666,6 +673,8 @@ void cmCTestMultiProcessHandler::PrintTestList()
count++; count++;
cmCTestTestHandler::cmCTestTestProperties& p = *it.second; cmCTestTestHandler::cmCTestTestProperties& p = *it.second;
// Don't worry if this fails, we are only showing the test list, not
// running the tests
cmWorkingDirectory workdir(p.Directory); cmWorkingDirectory workdir(p.Directory);
cmCTestRunTest testRun(*this); cmCTestRunTest testRun(*this);

View File

@ -14,6 +14,7 @@
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include <chrono> #include <chrono>
#include <cmAlgorithms.h> #include <cmAlgorithms.h>
#include <cstring>
#include <iomanip> #include <iomanip>
#include <ratio> #include <ratio>
#include <sstream> #include <sstream>
@ -248,11 +249,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
*this->TestHandler->LogFile << "Test time = " << buf << std::endl; *this->TestHandler->LogFile << "Test time = " << buf << std::endl;
} }
// Set the working directory to the tests directory to process Dart files.
{
cmWorkingDirectory workdir(this->TestProperties->Directory);
this->DartProcessing(); this->DartProcessing();
}
// if this is doing MemCheck then all the output needs to be put into // if this is doing MemCheck then all the output needs to be put into
// Output since that is what is parsed by cmCTestMemCheckHandler // Output since that is what is parsed by cmCTestMemCheckHandler
@ -338,6 +335,13 @@ bool cmCTestRunTest::StartAgain()
this->RunAgain = false; // reset this->RunAgain = false; // reset
// change to tests directory // change to tests directory
cmWorkingDirectory workdir(this->TestProperties->Directory); cmWorkingDirectory workdir(this->TestProperties->Directory);
if (workdir.Failed()) {
this->StartFailure("Failed to change working directory to " +
this->TestProperties->Directory + " : " +
std::strerror(workdir.GetLastResult()));
return true;
}
this->StartTest(this->TotalNumberOfTests); this->StartTest(this->TotalNumberOfTests);
return true; return true;
} }
@ -386,6 +390,37 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index); handler->PostProcessTest(this->TestResult, this->Index);
} }
void cmCTestRunTest::StartFailure(std::string const& output)
{
// Still need to log the Start message so the test summary records our
// attempt to start this test
cmCTestLog(this->CTest, HANDLER_OUTPUT,
std::setw(2 * getNumWidth(this->TotalNumberOfTests) + 8)
<< "Start "
<< std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
<< this->TestProperties->Index << ": "
<< this->TestProperties->Name << std::endl);
this->ProcessOutput.clear();
if (!output.empty()) {
*this->TestHandler->LogFile << output << std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE, output << std::endl);
}
this->TestResult.Properties = this->TestProperties;
this->TestResult.ExecutionTime = cmDuration::zero();
this->TestResult.CompressOutput = false;
this->TestResult.ReturnValue = -1;
this->TestResult.CompletionStatus = "Failed to start";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory;
this->TestResult.Output = output;
this->TestResult.FullCommandLine.clear();
this->TestProcess = cm::make_unique<cmProcess>(*this);
}
// Starts the execution of a test. Returns once it has started // Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t total) bool cmCTestRunTest::StartTest(size_t total)
{ {

View File

@ -74,6 +74,8 @@ public:
bool StartAgain(); bool StartAgain();
void StartFailure(std::string const& output);
cmCTest* GetCTest() const { return this->CTest; } cmCTest* GetCTest() const { return this->CTest; }
void FinalizeTest(); void FinalizeTest();

View File

@ -7,6 +7,7 @@
#include "cm_jsoncpp_value.h" #include "cm_jsoncpp_value.h"
#include "cmsys/Process.h" #include "cmsys/Process.h"
#include <chrono> #include <chrono>
#include <cstring>
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -1532,6 +1533,15 @@ int cmCTestSubmitHandler::ProcessHandler()
// change to the build directory so that we can uses a relative path // change to the build directory so that we can uses a relative path
// on windows since scp doesn't support "c:" a drive in the path // on windows since scp doesn't support "c:" a drive in the path
cmWorkingDirectory workdir(buildDirectory); cmWorkingDirectory workdir(buildDirectory);
if (workdir.Failed()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Failed to change directory to "
<< buildDirectory << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
ofs << " Failed to change directory to " << buildDirectory << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl;
return -1;
}
if (!this->SubmitUsingSCP(this->CTest->GetCTestConfiguration("ScpCommand"), if (!this->SubmitUsingSCP(this->CTest->GetCTestConfiguration("ScpCommand"),
"Testing/" + this->CTest->GetCurrentTag(), files, "Testing/" + this->CTest->GetCurrentTag(), files,
@ -1551,6 +1561,15 @@ int cmCTestSubmitHandler::ProcessHandler()
// change to the build directory so that we can uses a relative path // change to the build directory so that we can uses a relative path
// on windows since scp doesn't support "c:" a drive in the path // on windows since scp doesn't support "c:" a drive in the path
cmWorkingDirectory workdir(buildDirectory); cmWorkingDirectory workdir(buildDirectory);
if (workdir.Failed()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Failed to change directory to "
<< buildDirectory << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
ofs << " Failed to change directory to " << buildDirectory << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl;
return -1;
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" Change directory: " << buildDirectory << std::endl, " Change directory: " << buildDirectory << std::endl,
this->Quiet); this->Quiet);

View File

@ -6,6 +6,7 @@
#include <cmsys/Base64.h> #include <cmsys/Base64.h>
#include <cmsys/Directory.hxx> #include <cmsys/Directory.hxx>
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <cstring>
#include <functional> #include <functional>
#include <iomanip> #include <iomanip>
#include <iterator> #include <iterator>
@ -14,7 +15,6 @@
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <time.h> #include <time.h>
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
@ -85,6 +85,11 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
bool readit = false; bool readit = false;
{ {
cmWorkingDirectory workdir(fname); cmWorkingDirectory workdir(fname);
if (workdir.Failed()) {
this->SetError("Failed to change directory to " + fname + " : " +
std::strerror(workdir.GetLastResult()));
return false;
}
const char* testFilename; const char* testFilename;
if (cmSystemTools::FileExists("CTestTestfile.cmake")) { if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
// does the CTestTestfile.cmake exist ? // does the CTestTestfile.cmake exist ?

View File

@ -6,11 +6,11 @@
#include "cmsys/FStream.hxx" #include "cmsys/FStream.hxx"
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
#include <cstring>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h> #include <windows.h>
@ -1806,6 +1806,8 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
cmSystemTools::OutputOption outputflag, cmSystemTools::OutputOption outputflag,
std::vector<std::string> const& nativeOptions) std::vector<std::string> const& nativeOptions)
{ {
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
/** /**
* Run an executable command and put the stdout in output. * Run an executable command and put the stdout in output.
*/ */
@ -1813,9 +1815,17 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
output += "Change Dir: "; output += "Change Dir: ";
output += bindir; output += bindir;
output += "\n"; output += "\n";
if (workdir.Failed()) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Failed to change directory: ",
std::strerror(workdir.GetLastResult()));
output += "Failed to change directory: ";
output += std::strerror(workdir.GetLastResult());
output += "\n";
return 1;
}
int retVal; int retVal;
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
cmSystemTools::SetRunCommandHideConsole(true); cmSystemTools::SetRunCommandHideConsole(true);
std::string outputBuffer; std::string outputBuffer;
std::string* outputPtr = &outputBuffer; std::string* outputPtr = &outputBuffer;

View File

@ -6,12 +6,12 @@
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
#include <cstring>
#include <ctype.h> #include <ctype.h>
#include <iterator> #include <iterator>
#include <memory> // IWYU pragma: keep #include <memory> // IWYU pragma: keep
#include <sstream> #include <sstream>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <utility> #include <utility>
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
@ -3250,6 +3250,14 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// change to the tests directory and run cmake // change to the tests directory and run cmake
// use the cmake object instead of calling cmake // use the cmake object instead of calling cmake
cmWorkingDirectory workdir(bindir); cmWorkingDirectory workdir(bindir);
if (workdir.Failed()) {
this->IssueMessage(cmake::FATAL_ERROR,
"Failed to set working directory to " + bindir + " : " +
std::strerror(workdir.GetLastResult()));
cmSystemTools::SetFatalErrorOccured();
this->IsSourceFileTryCompile = false;
return 1;
}
// make sure the same generator is used // make sure the same generator is used
// use this program as the cmake to be run, it should not // use this program as the cmake to be run, it should not

View File

@ -4,10 +4,12 @@
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include <cerrno>
cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir) cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir)
{ {
this->OldDir = cmSystemTools::GetCurrentWorkingDirectory(); this->OldDir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(newdir); this->SetDirectory(newdir);
} }
cmWorkingDirectory::~cmWorkingDirectory() cmWorkingDirectory::~cmWorkingDirectory()
@ -15,10 +17,20 @@ cmWorkingDirectory::~cmWorkingDirectory()
this->Pop(); this->Pop();
} }
bool cmWorkingDirectory::SetDirectory(std::string const& newdir)
{
if (cmSystemTools::ChangeDirectory(newdir) == 0) {
this->ResultCode = 0;
return true;
}
this->ResultCode = errno;
return false;
}
void cmWorkingDirectory::Pop() void cmWorkingDirectory::Pop()
{ {
if (!this->OldDir.empty()) { if (!this->OldDir.empty()) {
cmSystemTools::ChangeDirectory(this->OldDir); this->SetDirectory(this->OldDir);
this->OldDir.clear(); this->OldDir.clear();
} }
} }

View File

@ -9,6 +9,12 @@
/** \class cmWorkingDirectory /** \class cmWorkingDirectory
* \brief An RAII class to manipulate the working directory. * \brief An RAII class to manipulate the working directory.
*
* The current working directory is set to the location given to the
* constructor. The working directory can be changed again as needed
* by calling SetDirectory(). When the object is destroyed, the destructor
* will restore the working directory to what it was when the object was
* created, regardless of any calls to SetDirectory() in the meantime.
*/ */
class cmWorkingDirectory class cmWorkingDirectory
{ {
@ -16,10 +22,21 @@ public:
cmWorkingDirectory(std::string const& newdir); cmWorkingDirectory(std::string const& newdir);
~cmWorkingDirectory(); ~cmWorkingDirectory();
bool SetDirectory(std::string const& newdir);
void Pop(); void Pop();
bool Failed() const { return ResultCode != 0; }
/** \return 0 if the last attempt to set the working directory was
* successful. If it failed, the value returned will be the
* \c errno value associated with the failure. A description
* of the error code can be obtained by passing the result
* to \c std::strerror().
*/
int GetLastResult() const { return ResultCode; }
private: private:
std::string OldDir; std::string OldDir;
int ResultCode;
}; };
#endif #endif

View File

@ -98,13 +98,13 @@
#include "cmsys/Glob.hxx" #include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include <algorithm> #include <algorithm>
#include <cstring>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <memory> // IWYU pragma: keep #include <memory> // IWYU pragma: keep
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <utility> #include <utility>
namespace { namespace {
@ -2209,6 +2209,15 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
{ {
// now run cmake on the CMakeLists file // now run cmake on the CMakeLists file
cmWorkingDirectory workdir(destPath); cmWorkingDirectory workdir(destPath);
if (workdir.Failed()) {
// We created the directory and we were able to copy the CMakeLists.txt
// file to it, so we wouldn't expect to get here unless the default
// permissions are questionable or some other process has deleted the
// directory
std::cerr << "Failed to change to directory " << destPath << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl;
return 1;
}
std::vector<std::string> args2; std::vector<std::string> args2;
args2.push_back(args[0]); args2.push_back(args[0]);
args2.push_back(destPath); args2.push_back(destPath);

View File

@ -0,0 +1 @@
Failed to change working directory to .*[/\\]buildAndTestNoBuildDir[/\\]CMakeLists.txt :

View File

@ -0,0 +1 @@
Failed to change working directory to .*[/\\]dirNotExist-build[/\\]thisDirWillNotExist :