update_engine: Use utils::FileSize when finding the size of a file.

The utils::FileSize funciton can find the size of a block device correctly.
Use it instead of the adhoc methods used around the codebase.

BUG=chromium:415867
TEST=Ran a butterfly-paladin tryjob with --hwtest.

Change-Id: Id6fd37f04b136b4265bde9b1f56c379a5d9c30f9
Reviewed-on: https://chromium-review.googlesource.com/217418
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
diff --git a/download_action.cc b/download_action.cc
index 5b3ffeb..6871f60 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -117,15 +117,15 @@
   //  1. the p2p file didn't get properly synced to stable storage; or
   //  2. the file was deleted at bootup (it's in /var/cache after all); or
   //  3. other reasons
-  struct stat statbuf;
-  if (fstat(p2p_sharing_fd_, &statbuf) != 0) {
+  off_t p2p_size = utils::FileSize(p2p_sharing_fd_);
+  if (p2p_size < 0) {
     PLOG(ERROR) << "Error getting file status for p2p file";
     CloseP2PSharingFd(true);  // Delete p2p file.
     return;
   }
-  if (statbuf.st_size < file_offset) {
+  if (p2p_size < file_offset) {
     LOG(ERROR) << "Wanting to write to file offset " << file_offset
-               << " but existing p2p file is only " << statbuf.st_size
+               << " but existing p2p file is only " << p2p_size
                << " bytes.";
     CloseP2PSharingFd(true);  // Delete p2p file.
     return;
diff --git a/extent_writer_unittest.cc b/extent_writer_unittest.cc
index fef3343..a1b254d 100644
--- a/extent_writer_unittest.cc
+++ b/extent_writer_unittest.cc
@@ -70,9 +70,7 @@
   EXPECT_TRUE(direct_writer.Write(bytes.data(), bytes.size()));
   EXPECT_TRUE(direct_writer.End());
 
-  struct stat stbuf;
-  EXPECT_EQ(0, fstat(fd(), &stbuf));
-  EXPECT_EQ(kBlockSize + bytes.size(), stbuf.st_size);
+  EXPECT_EQ(kBlockSize + bytes.size(), utils::FileSize(fd()));
 
   vector<char> result_file;
   EXPECT_TRUE(utils::ReadFile(path(), &result_file));
@@ -139,9 +137,7 @@
   }
   EXPECT_TRUE(direct_writer.End());
 
-  struct stat stbuf;
-  EXPECT_EQ(0, fstat(fd(), &stbuf));
-  EXPECT_EQ(data.size(), stbuf.st_size);
+  EXPECT_EQ(data.size(), utils::FileSize(fd()));
 
   vector<char> result_file;
   EXPECT_TRUE(utils::ReadFile(path(), &result_file));
@@ -190,9 +186,7 @@
   ASSERT_TRUE(zero_pad_writer.Write(&data[0], bytes_to_write));
   EXPECT_TRUE(zero_pad_writer.End());
 
-  struct stat stbuf;
-  EXPECT_EQ(0, fstat(fd(), &stbuf));
-  EXPECT_EQ(data.size(), stbuf.st_size);
+  EXPECT_EQ(data.size(), utils::FileSize(fd()));
 
   vector<char> result_file;
   EXPECT_TRUE(utils::ReadFile(path(), &result_file));
diff --git a/p2p_manager.cc b/p2p_manager.cc
index 5039747..8c48601 100644
--- a/p2p_manager.cc
+++ b/p2p_manager.cc
@@ -693,13 +693,7 @@
   if (path.empty())
     return -1;
 
-  struct stat statbuf;
-  if (stat(path.value().c_str(), &statbuf) != 0) {
-    PLOG(ERROR) << "Error getting file status for " << path.value();
-    return -1;
-  }
-
-  return statbuf.st_size;
+  return utils::FileSize(path.value());
 }
 
 ssize_t P2PManagerImpl::FileGetExpectedSize(const string& file_id) {
diff --git a/p2p_manager_unittest.cc b/p2p_manager_unittest.cc
index 56ba33b..456c8ad 100644
--- a/p2p_manager_unittest.cc
+++ b/p2p_manager_unittest.cc
@@ -208,19 +208,19 @@
 static bool CheckP2PFile(const string& p2p_dir, const string& file_name,
                          ssize_t expected_size, ssize_t expected_size_xattr) {
   string path = p2p_dir + "/" + file_name;
-  struct stat statbuf;
   char ea_value[64] = { 0 };
   ssize_t ea_size;
 
-  if (stat(path.c_str(), &statbuf) != 0) {
+  off_t p2p_size = utils::FileSize(path);
+  if (p2p_size < 0) {
     LOG(ERROR) << "File " << path << " does not exist";
     return false;
   }
 
   if (expected_size != 0) {
-    if (statbuf.st_size != expected_size) {
+    if (p2p_size != expected_size) {
       LOG(ERROR) << "Expected size " << expected_size
-                 << " but size was " << statbuf.st_size;
+                 << " but size was " << p2p_size;
       return false;
     }
   }
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index 3b8f718..ee5a79b 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -208,7 +208,7 @@
     if (utils::SetContainsKey(visited_inodes, fs_iter.GetStat().st_ino))
       continue;
     visited_inodes.insert(fs_iter.GetStat().st_ino);
-    off_t dst_size = fs_iter.GetStat().st_size;
+    off_t dst_size = fs_iter.GetFileSize();
     if (dst_size == 0)
       continue;
 
@@ -702,11 +702,11 @@
   }
 
   // Do we have an original file to consider?
-  struct stat old_stbuf;
+  off_t old_size = 0;
   bool original = !old_filename.empty();
-  if (original && 0 != stat(old_filename.c_str(), &old_stbuf)) {
+  if (original && (old_size = utils::FileSize(old_filename)) < 0) {
     // If stat-ing the old file fails, it should be because it doesn't exist.
-    TEST_AND_RETURN_FALSE(errno == ENOTDIR || errno == ENOENT);
+    TEST_AND_RETURN_FALSE(!utils::FileExists(old_filename.c_str()));
     original = false;
   }
 
@@ -764,8 +764,7 @@
     } else {
       Extent* src_extent = operation.add_src_extents();
       src_extent->set_start_block(0);
-      src_extent->set_num_blocks(
-          (old_stbuf.st_size + kBlockSize - 1) / kBlockSize);
+      src_extent->set_num_blocks((old_size + kBlockSize - 1) / kBlockSize);
     }
     operation.set_src_length(old_data.size());
   }
diff --git a/payload_generator/extent_mapper.cc b/payload_generator/extent_mapper.cc
index ace463f..5e363c7 100644
--- a/payload_generator/extent_mapper.cc
+++ b/payload_generator/extent_mapper.cc
@@ -49,13 +49,12 @@
   ScopedFdCloser fd_closer(&fd);
 
   // Get file size in blocks
-  rc = fstat(fd, &stbuf);
-  if (rc < 0) {
-    perror("fstat");
+  off_t file_size = utils::FileSize(fd);
+  if (file_size < 0) {
     return false;
   }
-  CHECK_LE(chunk_offset, stbuf.st_size);
-  off_t size = stbuf.st_size - chunk_offset;
+  CHECK_LE(chunk_offset, file_size);
+  off_t size = file_size - chunk_offset;
   if (chunk_size != -1) {
     size = std::min(size, chunk_size);
   }
diff --git a/payload_generator/extent_mapper_unittest.cc b/payload_generator/extent_mapper_unittest.cc
index f56cca0..3e87cdc 100644
--- a/payload_generator/extent_mapper_unittest.cc
+++ b/payload_generator/extent_mapper_unittest.cc
@@ -54,9 +54,9 @@
     }
   }
 
-  struct stat stbuf;
-  EXPECT_EQ(0, stat(kFilename.c_str(), &stbuf));
-  EXPECT_EQ(blocks.size(), (stbuf.st_size + block_size - 1)/block_size);
+  off_t file_size = utils::FileSize(kFilename);
+  EXPECT_GT(file_size, 0);
+  EXPECT_EQ(blocks.size(), (file_size + block_size - 1)/block_size);
 
   // Map a 2-block chunk at offset |block_size|.
   vector<Extent> chunk_extents;
diff --git a/payload_generator/filesystem_iterator.cc b/payload_generator/filesystem_iterator.cc
index b7455fa..edede08 100644
--- a/payload_generator/filesystem_iterator.cc
+++ b/payload_generator/filesystem_iterator.cc
@@ -56,6 +56,11 @@
   }
 }
 
+// Returns the size of the current file
+off_t FilesystemIterator::GetFileSize() const {
+  return utils::FileSize(GetFullPath());
+}
+
 // Returns full path for current file
 std::string FilesystemIterator::GetFullPath() const {
   return root_path_ + GetPartialPath();
diff --git a/payload_generator/filesystem_iterator.h b/payload_generator/filesystem_iterator.h
index 7df250f..8248479 100644
--- a/payload_generator/filesystem_iterator.h
+++ b/payload_generator/filesystem_iterator.h
@@ -47,6 +47,9 @@
     return stbuf_;
   }
 
+  // Returns the size of the current file.
+  off_t GetFileSize() const;
+
   // Returns full path for current file.
   std::string GetFullPath() const;