Move and rename FdopenPlatformFile to file_util

This CL also improves error handling and adds a unit test.

BUG=322664

Review URL: https://codereview.chromium.org/319543004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275986 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: 4d358286200983a8b9caef7c511510397e583658
diff --git a/base/file_util.h b/base/file_util.h
index 9c9072f..bb04e62 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -308,6 +308,10 @@
 // Closes file opened by OpenFile. Returns true on success.
 BASE_EXPORT bool CloseFile(FILE* file);
 
+// Associates a standard FILE stream with an existing File. Note that this
+// functions take ownership of the existing File.
+BASE_EXPORT FILE* FileToFILE(File file, const char* mode);
+
 // Truncates an open file to end at the location of the current file pointer.
 // This is a cross-platform analog to Windows' SetEndOfFile() function.
 BASE_EXPORT bool TruncateFile(FILE* file);
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index d9328ee..92e8cad 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -654,6 +654,16 @@
   return result;
 }
 
+// NaCl doesn't implement system calls to open files directly.
+#if !defined(OS_NACL)
+FILE* FileToFILE(File file, const char* mode) {
+  FILE* stream = fdopen(file.GetPlatformFile(), mode);
+  if (stream)
+    file.TakePlatformFile();
+  return stream;
+}
+#endif  // !defined(OS_NACL)
+
 int ReadFile(const FilePath& filename, char* data, int max_size) {
   ThreadRestrictions::AssertIOAllowed();
   int fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY));
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 83f211f..239563d 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -1685,6 +1685,21 @@
   }
 }
 
+TEST_F(FileUtilTest, FileToFILE) {
+  File file;
+  FILE* stream = FileToFILE(file.Pass(), "w");
+  EXPECT_FALSE(stream);
+
+  FilePath file_name = temp_dir_.path().Append(FPL("The file.txt"));
+  file = File(file_name, File::FLAG_CREATE | File::FLAG_WRITE);
+  EXPECT_TRUE(file.IsValid());
+
+  stream = FileToFILE(file.Pass(), "w");
+  EXPECT_TRUE(stream);
+  EXPECT_FALSE(file.IsValid());
+  EXPECT_TRUE(CloseFile(stream));
+}
+
 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
   FilePath temp_dir;
   ASSERT_TRUE(CreateNewTempDirectory(FilePath::StringType(), &temp_dir));
diff --git a/base/platform_file.h b/base/platform_file.h
index a2693a7..27686d1 100644
--- a/base/platform_file.h
+++ b/base/platform_file.h
@@ -134,8 +134,6 @@
 BASE_EXPORT PlatformFileError ErrnoToPlatformFileError(int saved_errno);
 #endif
 
-BASE_EXPORT FILE* FdopenPlatformFile(PlatformFile file, const char* mode);
-
 // Closes a file handle. Returns |true| on success and |false| otherwise.
 BASE_EXPORT bool ClosePlatformFile(PlatformFile file);
 
diff --git a/base/platform_file_posix.cc b/base/platform_file_posix.cc
index ff92b90..cee1f61 100644
--- a/base/platform_file_posix.cc
+++ b/base/platform_file_posix.cc
@@ -117,13 +117,6 @@
 
 }  // namespace
 
-// NaCl doesn't implement system calls to open files directly.
-#if !defined(OS_NACL)
-FILE* FdopenPlatformFile(PlatformFile file, const char* mode) {
-  return fdopen(file, mode);
-}
-#endif  // !defined(OS_NACL)
-
 bool ClosePlatformFile(PlatformFile file) {
   base::ThreadRestrictions::AssertIOAllowed();
   return !IGNORE_EINTR(close(file));