Setup a temporary directory for update_engine_sideload.

When running update_engine_sideload from recovery, the default temp
directory (/data/misc/update_engine/tmp) is not available. This
directory is currently used to store a blob when applying a bspatch
from a child process. This patch uses /tmp/update_engine_sideload as
a temporary directory when running update_engine_sideload from recovery.

Bug: 27178350
TEST=`adb sideload` an incremental update.

(cherry picked from commit 3295102ed64107f966d4cf8bfe733bb936646630)

Change-Id: Icef9dd48b00991975bcf6c39a148f952ef43d9e3
diff --git a/common/utils.cc b/common/utils.cc
index 19c63c0..166cfb4 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -87,6 +87,11 @@
 // The path to the kernel's boot_id.
 const char kBootIdPath[] = "/proc/sys/kernel/random/boot_id";
 
+// A pointer to a null-terminated string containing the root directory where all
+// the temporary files should be created. If null, the system default is used
+// instead.
+const char* root_temp_dir = nullptr;
+
 // Return true if |disk_name| is an MTD or a UBI device. Note that this test is
 // simply based on the name of the device.
 bool IsMtdDeviceName(const string& disk_name) {
@@ -143,13 +148,17 @@
   }
 
   base::FilePath temp_dir;
+  if (root_temp_dir) {
+    temp_dir = base::FilePath(root_temp_dir);
+  } else {
 #ifdef __ANDROID__
-  temp_dir = base::FilePath(constants::kNonVolatileDirectory).Append("tmp");
+    temp_dir = base::FilePath(constants::kNonVolatileDirectory).Append("tmp");
+#else
+    TEST_AND_RETURN_FALSE(base::GetTempDir(&temp_dir));
+#endif  // __ANDROID__
+  }
   if (!base::PathExists(temp_dir))
     TEST_AND_RETURN_FALSE(base::CreateDirectory(temp_dir));
-#else
-  TEST_AND_RETURN_FALSE(base::GetTempDir(&temp_dir));
-#endif  // __ANDROID__
   *template_path = temp_dir.Append(path);
   return true;
 }
@@ -158,6 +167,10 @@
 
 namespace utils {
 
+void SetRootTempDir(const char* new_root_temp_dir) {
+  root_temp_dir = new_root_temp_dir;
+}
+
 string ParseECVersion(string input_line) {
   base::TrimWhitespaceASCII(input_line, base::TRIM_ALL, &input_line);
 
diff --git a/common/utils.h b/common/utils.h
index 63328b6..24bf702 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -131,6 +131,13 @@
 // only returns true if "/dev/ubi%d_0" becomes available in |timeout| seconds.
 bool TryAttachingUbiVolume(int volume_num, int timeout);
 
+// Setup the directory |new_root_temp_dir| to be used as the root directory for
+// temporary files instead of the system's default. If the directory doesn't
+// exists, it will be created when first used.
+// NOTE: The memory pointed by |new_root_temp_dir| must be available until this
+// function is called again with a different value.
+void SetRootTempDir(const char* new_root_temp_dir);
+
 // If |base_filename_template| is neither absolute (starts with "/") nor
 // explicitly relative to the current working directory (starts with "./" or
 // "../"), then it is prepended the system's temporary directory. On success,
diff --git a/sideload_main.cc b/sideload_main.cc
index 43d0f93..35ed11b 100644
--- a/sideload_main.cc
+++ b/sideload_main.cc
@@ -43,6 +43,11 @@
 using std::vector;
 using update_engine::UpdateStatus;
 
+namespace {
+// The root directory used for temporary files in update_engine_sideload.
+const char kSideloadRootTempDir[] = "/tmp/update_engine_sideload";
+}  // namespace
+
 namespace chromeos_update_engine {
 namespace {
 
@@ -207,6 +212,10 @@
   // xz-embedded requires to initialize its CRC-32 table once on startup.
   xz_crc32_init();
 
+  // When called from recovery, /data is not accessible, so we need to use
+  // /tmp for temporary files.
+  chromeos_update_engine::utils::SetRootTempDir(kSideloadRootTempDir);
+
   vector<string> headers = base::SplitString(
       FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);