summaryrefslogtreecommitdiffstats
path: root/src/test.cc
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2012-01-06 19:34:10 (GMT)
committerEvan Martin <martine@danga.com>2012-01-06 19:34:10 (GMT)
commit36660e473b7f38317a38cc5a297ba18166191cf5 (patch)
tree063a8bc98ce298b911a81193ee2999ed2be03d9d /src/test.cc
parentc633f316d74375b49808a0e98511ff224d519746 (diff)
downloadNinja-36660e473b7f38317a38cc5a297ba18166191cf5.zip
Ninja-36660e473b7f38317a38cc5a297ba18166191cf5.tar.gz
Ninja-36660e473b7f38317a38cc5a297ba18166191cf5.tar.bz2
migrate tempdir code to test.cc
Diffstat (limited to 'src/test.cc')
-rw-r--r--src/test.cc91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/test.cc b/src/test.cc
index 925a6cb..f5b037f 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -16,7 +16,57 @@
#include <algorithm>
+#include <errno.h>
+
#include "parsers.h"
+#include "util.h"
+
+namespace {
+
+#ifdef _WIN32
+#ifndef _mktemp_s
+/// mingw has no mktemp. Implement one with the same type as the one
+/// found in the Windows API.
+int _mktemp_s(char* templ) {
+ char* ofs = strchr(templ, 'X');
+ sprintf(ofs, "%d", rand() % 1000000);
+ return 0;
+}
+#endif
+
+/// Windows has no mkdtemp. Implement it in terms of _mktemp_s.
+char* mkdtemp(char* name_template) {
+ int err = _mktemp_s(name_template);
+ if (err < 0) {
+ perror("_mktemp_s");
+ return NULL;
+ }
+
+ err = _mkdir(name_template);
+ if (err < 0) {
+ perror("mkdir");
+ return NULL;
+ }
+
+ return name_template;
+}
+#endif // WIN32
+
+string GetSystemTempDir() {
+#ifdef _WIN32
+ char buf[1024];
+ if (!GetTempPath(sizeof(buf), buf))
+ return "";
+ return buf;
+#else
+ const char* tempdir = getenv("TMPDIR");
+ if (tempdir)
+ return tempdir;
+ return "/tmp";
+#endif
+}
+
+} // anonymous namespace
StateTestWithBuiltinRules::StateTestWithBuiltinRules() {
AssertParse(&state_,
@@ -74,3 +124,44 @@ int VirtualFileSystem::RemoveFile(const string& path) {
return 1;
}
}
+
+void ScopedTempDir::CreateAndEnter(const string& name) {
+ // First change into the system temp dir and save it for cleanup.
+ start_dir_ = GetSystemTempDir();
+ if (start_dir_.empty())
+ Fatal("couldn't get system temp dir");
+ if (chdir(start_dir_.c_str()) < 0)
+ Fatal("chdir: %s", strerror(errno));
+
+ // Create a temporary subdirectory of that.
+ char name_template[1024];
+ strcpy(name_template, name.c_str());
+ strcat(name_template, "-XXXXXX");
+ char* tempname = mkdtemp(name_template);
+ if (!tempname)
+ Fatal("mkdtemp: %s", strerror(errno));
+ temp_dir_name_ = tempname;
+
+ // chdir into the new temporary directory.
+ if (chdir(temp_dir_name_.c_str()) < 0)
+ Fatal("chdir: %s", strerror(errno));
+}
+
+void ScopedTempDir::Cleanup() {
+ if (temp_dir_name_.empty())
+ return; // Something went wrong earlier.
+
+ // Move out of the directory we're about to clobber.
+ if (chdir(start_dir_.c_str()) < 0)
+ Fatal("chdir: %s", strerror(errno));
+
+#ifdef _WIN32
+ string command = "rmdir /s /q " + temp_dir_name_;
+#else
+ string command = "rm -rf " + temp_dir_name_;
+#endif
+ if (system(command.c_str()) < 0)
+ Fatal("system: %s", strerror(errno));
+
+ temp_dir_name_.clear();
+}