Write mkdirs in more idiomatic C++ style.

~ Rewrote mkdirs to be in C++ style.
~ Replaced adb_dir{start,stop} with std::string params and (r)find.
+ Added test for mkdirs.

Also make base/test_utils.h public and support temporary directories
as well as files.

Change-Id: I6fcbdc5e0099f3359d3aac6b00c436f250ca1329
diff --git a/base/Android.mk b/base/Android.mk
index 7bd317b..4e135f6 100644
--- a/base/Android.mk
+++ b/base/Android.mk
@@ -21,6 +21,7 @@
     logging.cpp \
     stringprintf.cpp \
     strings.cpp \
+    test_utils.cpp \
 
 libbase_test_src_files := \
     file_test.cpp \
@@ -28,7 +29,6 @@
     stringprintf_test.cpp \
     strings_test.cpp \
     test_main.cpp \
-    test_utils.cpp \
 
 libbase_cppflags := \
     -Wall \
diff --git a/base/file_test.cpp b/base/file_test.cpp
index b138094..4056684 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -24,7 +24,7 @@
 
 #include <string>
 
-#include "test_utils.h"
+#include "base/test_utils.h"
 
 TEST(file, ReadFileToString_ENOENT) {
   std::string s("hello");
@@ -47,10 +47,10 @@
 TEST(file, WriteStringToFile) {
   TemporaryFile tf;
   ASSERT_TRUE(tf.fd != -1);
-  ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.filename))
+  ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.path))
     << strerror(errno);
   std::string s;
-  ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))
     << strerror(errno);
   EXPECT_EQ("abc", s);
 }
@@ -61,16 +61,16 @@
 TEST(file, WriteStringToFile2) {
   TemporaryFile tf;
   ASSERT_TRUE(tf.fd != -1);
-  ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.filename, 0660,
+  ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.path, 0660,
                                                getuid(), getgid()))
       << strerror(errno);
   struct stat sb;
-  ASSERT_EQ(0, stat(tf.filename, &sb));
+  ASSERT_EQ(0, stat(tf.path, &sb));
   ASSERT_EQ(0660U, static_cast<unsigned int>(sb.st_mode & ~S_IFMT));
   ASSERT_EQ(getuid(), sb.st_uid);
   ASSERT_EQ(getgid(), sb.st_gid);
   std::string s;
-  ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))
     << strerror(errno);
   EXPECT_EQ("abc", s);
 }
@@ -109,7 +109,7 @@
   ASSERT_TRUE(tf.fd != -1);
   ASSERT_TRUE(android::base::WriteFully(tf.fd, "abc", 3));
   std::string s;
-  ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))
     << strerror(errno);
   EXPECT_EQ("abc", s);
 }
diff --git a/base/test_utils.h b/base/include/base/test_utils.h
similarity index 68%
rename from base/test_utils.h
rename to base/include/base/test_utils.h
index 132d3a7..83f0f1c 100644
--- a/base/test_utils.h
+++ b/base/include/base/test_utils.h
@@ -17,16 +17,37 @@
 #ifndef TEST_UTILS_H
 #define TEST_UTILS_H
 
+#include <string>
+
+#include <base/macros.h>
+
 class TemporaryFile {
  public:
   TemporaryFile();
   ~TemporaryFile();
 
   int fd;
-  char filename[1024];
+  char path[1024];
 
  private:
-  void init(const char* tmp_dir);
+  void init(const std::string& tmp_dir);
+
+  DISALLOW_COPY_AND_ASSIGN(TemporaryFile);
 };
 
+#if !defined(_WIN32)
+class TemporaryDir {
+ public:
+  TemporaryDir();
+  ~TemporaryDir();
+
+  char path[1024];
+
+ private:
+  bool init(const std::string& tmp_dir);
+
+  DISALLOW_COPY_AND_ASSIGN(TemporaryDir);
+};
+#endif
+
 #endif // TEST_UTILS_H
diff --git a/base/logging_test.cpp b/base/logging_test.cpp
index c91857a..1a92c94 100644
--- a/base/logging_test.cpp
+++ b/base/logging_test.cpp
@@ -21,7 +21,7 @@
 
 #include "base/file.h"
 #include "base/stringprintf.h"
-#include "test_utils.h"
+#include "base/test_utils.h"
 
 #include <gtest/gtest.h>
 
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 0517bc7..dceb8b7 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "test_utils.h"
+#include "base/test_utils.h"
 
 #include <fcntl.h>
 #include <stdio.h>
@@ -26,34 +26,55 @@
 #include <windows.h>
 #endif
 
-TemporaryFile::TemporaryFile() {
+#include <string>
+
+static std::string GetSystemTempDir() {
 #if defined(__ANDROID__)
-  init("/data/local/tmp");
+  return "/data/local/tmp";
 #elif defined(_WIN32)
   char wd[MAX_PATH] = {};
   _getcwd(wd, sizeof(wd));
-  init(wd);
+  return wd;
 #else
-  init("/tmp");
+  return "/tmp";
 #endif
 }
 
+TemporaryFile::TemporaryFile() {
+  init(GetSystemTempDir());
+}
+
 TemporaryFile::~TemporaryFile() {
   close(fd);
-  unlink(filename);
+  unlink(path);
 }
 
-void TemporaryFile::init(const char* tmp_dir) {
-  snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
+void TemporaryFile::init(const std::string& tmp_dir) {
+  snprintf(path, sizeof(path), "%s/TemporaryFile-XXXXXX", tmp_dir.c_str());
 #if !defined(_WIN32)
-  fd = mkstemp(filename);
+  fd = mkstemp(path);
 #else
   // Windows doesn't have mkstemp, and tmpfile creates the file in the root
   // directory, requiring root (?!) permissions. We have to settle for mktemp.
-  if (mktemp(filename) == nullptr) {
+  if (mktemp(path) == nullptr) {
     abort();
   }
 
-  fd = open(filename, O_RDWR | O_NOINHERIT | O_CREAT, _S_IREAD | _S_IWRITE);
+  fd = open(path, O_RDWR | O_NOINHERIT | O_CREAT, _S_IREAD | _S_IWRITE);
 #endif
 }
+
+#if !defined(_WIN32)
+TemporaryDir::TemporaryDir() {
+  init(GetSystemTempDir());
+}
+
+TemporaryDir::~TemporaryDir() {
+  rmdir(path);
+}
+
+bool TemporaryDir::init(const std::string& tmp_dir) {
+  snprintf(path, sizeof(path), "%s/TemporaryDir-XXXXXX", tmp_dir.c_str());
+  return (mkdtemp(path) != nullptr);
+}
+#endif