summaryrefslogtreecommitdiff
path: root/chromium/base/files
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/files')
-rw-r--r--chromium/base/files/file_descriptor_watcher_posix.h2
-rw-r--r--chromium/base/files/file_enumerator.h6
-rw-r--r--chromium/base/files/file_path.cc41
-rw-r--r--chromium/base/files/file_path.h2
-rw-r--r--chromium/base/files/file_path_watcher_linux.cc2
-rw-r--r--chromium/base/files/file_path_watcher_unittest.cc1
-rw-r--r--chromium/base/files/file_util.cc16
-rw-r--r--chromium/base/files/file_util.h54
-rw-r--r--chromium/base/files/file_util_posix.cc39
-rw-r--r--chromium/base/files/file_util_unittest.cc88
-rw-r--r--chromium/base/files/file_util_win.cc8
-rw-r--r--chromium/base/files/important_file_writer.cc23
-rw-r--r--chromium/base/files/important_file_writer_cleaner_unittest.cc2
-rw-r--r--chromium/base/files/memory_mapped_file.cc1
-rw-r--r--chromium/base/files/memory_mapped_file_win.cc1
-rw-r--r--chromium/base/files/scoped_file.h1
16 files changed, 202 insertions, 85 deletions
diff --git a/chromium/base/files/file_descriptor_watcher_posix.h b/chromium/base/files/file_descriptor_watcher_posix.h
index 3230350efb6..51958d19ccb 100644
--- a/chromium/base/files/file_descriptor_watcher_posix.h
+++ b/chromium/base/files/file_descriptor_watcher_posix.h
@@ -9,7 +9,7 @@
#include "base/base_export.h"
#include "base/callback.h"
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/base/files/file_enumerator.h b/chromium/base/files/file_enumerator.h
index de702e1ca6c..b2bd5ab8dd9 100644
--- a/chromium/base/files/file_enumerator.h
+++ b/chromium/base/files/file_enumerator.h
@@ -37,9 +37,9 @@ namespace base {
//
// Example:
//
-// base::FileEnumerator enum(my_dir, false, base::FileEnumerator::FILES,
-// FILE_PATH_LITERAL("*.txt"));
-// for (base::FilePath name = enum.Next(); !name.empty(); name = enum.Next())
+// base::FileEnumerator e(my_dir, false, base::FileEnumerator::FILES,
+// FILE_PATH_LITERAL("*.txt"));
+// for (base::FilePath name = e.Next(); !name.empty(); name = e.Next())
// ...
class BASE_EXPORT FileEnumerator {
public:
diff --git a/chromium/base/files/file_path.cc b/chromium/base/files/file_path.cc
index f1a4b0a9bf6..56c02d2bfc7 100644
--- a/chromium/base/files/file_path.cc
+++ b/chromium/base/files/file_path.cc
@@ -40,20 +40,6 @@ const char* const kCommonDoubleExtensionSuffixes[] = {"gz", "xz", "bz2", "z",
"bz"};
const char* const kCommonDoubleExtensions[] = { "user.js" };
-// Compatibility shim for cross-platform code that passes a StringPieceType to a
-// string utility function. Most of these functions are only implemented for
-// base::StringPiece and base::StringPiece16, which is why base::WStringPieces
-// need to be converted.
-#if defined(OS_WIN)
-StringPiece16 AsCommonStringPiece(WStringPiece str) {
- return AsStringPiece16(str);
-}
-#else
-StringPiece AsCommonStringPiece(StringPiece str) {
- return str;
-}
-#endif
-
const FilePath::CharType kStringTerminator = FILE_PATH_LITERAL('\0');
// If this FilePath contains a drive letter specification, returns the
@@ -84,8 +70,7 @@ bool EqualDriveLetterCaseInsensitive(StringPieceType a, StringPieceType b) {
StringPieceType a_letter(a.substr(0, a_letter_pos + 1));
StringPieceType b_letter(b.substr(0, b_letter_pos + 1));
- if (!StartsWith(AsCommonStringPiece(a_letter), AsCommonStringPiece(b_letter),
- CompareCase::INSENSITIVE_ASCII))
+ if (!StartsWith(a_letter, b_letter, CompareCase::INSENSITIVE_ASCII))
return false;
StringPieceType a_rest(a.substr(a_letter_pos + 1));
@@ -156,13 +141,13 @@ StringType::size_type ExtensionSeparatorPosition(const StringType& path) {
for (auto* i : kCommonDoubleExtensions) {
StringType extension(path, penultimate_dot + 1);
- if (LowerCaseEqualsASCII(AsCommonStringPiece(extension), i))
+ if (LowerCaseEqualsASCII(extension, i))
return penultimate_dot;
}
StringType extension(path, last_dot + 1);
for (auto* i : kCommonDoubleExtensionSuffixes) {
- if (LowerCaseEqualsASCII(AsCommonStringPiece(extension), i)) {
+ if (LowerCaseEqualsASCII(extension, i)) {
if ((last_dot - penultimate_dot) <= 5U &&
(last_dot - penultimate_dot) > 1U) {
return penultimate_dot;
@@ -201,7 +186,7 @@ FilePath::~FilePath() = default;
FilePath& FilePath::operator=(const FilePath& that) = default;
-FilePath& FilePath::operator=(FilePath&& that) = default;
+FilePath& FilePath::operator=(FilePath&& that) noexcept = default;
bool FilePath::operator==(const FilePath& that) const {
#if defined(FILE_PATH_USES_DRIVE_LETTERS)
@@ -295,9 +280,7 @@ bool FilePath::AppendRelativePath(const FilePath& child,
// never case sensitive.
if ((FindDriveLetter(*parent_comp) != StringType::npos) &&
(FindDriveLetter(*child_comp) != StringType::npos)) {
- if (!StartsWith(AsCommonStringPiece(*parent_comp),
- AsCommonStringPiece(*child_comp),
- CompareCase::INSENSITIVE_ASCII))
+ if (!StartsWith(*parent_comp, *child_comp, CompareCase::INSENSITIVE_ASCII))
return false;
++parent_comp;
++child_comp;
@@ -613,21 +596,19 @@ bool FilePath::ReferencesParent() const {
#if defined(OS_WIN)
string16 FilePath::LossyDisplayName() const {
- return string16(as_u16cstr(path_.data()), path_.size());
+ return AsString16(path_);
}
std::string FilePath::MaybeAsASCII() const {
- if (base::IsStringASCII(AsCommonStringPiece(path_)))
- return UTF16ToASCII(AsCommonStringPiece(path_));
- return std::string();
+ return base::IsStringASCII(path_) ? WideToASCII(path_) : std::string();
}
std::string FilePath::AsUTF8Unsafe() const {
- return UTF16ToUTF8(AsCommonStringPiece(value()));
+ return WideToUTF8(value());
}
string16 FilePath::AsUTF16Unsafe() const {
- return string16(AsCommonStringPiece(value()));
+ return WideToUTF16(value());
}
// static
@@ -637,7 +618,7 @@ FilePath FilePath::FromUTF8Unsafe(StringPiece utf8) {
// static
FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
- return FilePath(WStringPiece(as_wcstr(utf16.data()), utf16.size()));
+ return FilePath(AsWStringPiece(utf16));
}
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -693,7 +674,7 @@ FilePath FilePath::FromUTF16Unsafe(StringPiece16 utf16) {
void FilePath::WriteToPickle(Pickle* pickle) const {
#if defined(OS_WIN)
- pickle->WriteString16(AsCommonStringPiece(path_));
+ pickle->WriteString16(AsStringPiece16(path_));
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
pickle->WriteString(path_);
#else
diff --git a/chromium/base/files/file_path.h b/chromium/base/files/file_path.h
index 4e23f71a92a..2160fdaca31 100644
--- a/chromium/base/files/file_path.h
+++ b/chromium/base/files/file_path.h
@@ -193,7 +193,7 @@ class BASE_EXPORT FilePath {
FilePath(FilePath&& that) noexcept;
// Replaces the contents with those of |that|, which is left in valid but
// unspecified state.
- FilePath& operator=(FilePath&& that);
+ FilePath& operator=(FilePath&& that) noexcept;
bool operator==(const FilePath& that) const;
diff --git a/chromium/base/files/file_path_watcher_linux.cc b/chromium/base/files/file_path_watcher_linux.cc
index 563e0806758..7a04ac7dfef 100644
--- a/chromium/base/files/file_path_watcher_linux.cc
+++ b/chromium/base/files/file_path_watcher_linux.cc
@@ -38,7 +38,7 @@
#include "base/threading/platform_thread.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
+#include "base/trace_event/base_tracing.h"
namespace base {
diff --git a/chromium/base/files/file_path_watcher_unittest.cc b/chromium/base/files/file_path_watcher_unittest.cc
index ccefc27666b..055e0af45d9 100644
--- a/chromium/base/files/file_path_watcher_unittest.cc
+++ b/chromium/base/files/file_path_watcher_unittest.cc
@@ -20,6 +20,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/base/files/file_util.cc b/chromium/base/files/file_util.cc
index 546934b7084..27a2e428d54 100644
--- a/chromium/base/files/file_util.cc
+++ b/chromium/base/files/file_util.cc
@@ -27,6 +27,22 @@
namespace base {
#if !defined(OS_NACL_NONSFI)
+namespace {
+
+void DeleteFileHelper(const FilePath& path) {
+ DeleteFile(path, /*recursive=*/false);
+}
+
+} // namespace
+
+OnceCallback<void(const FilePath&)> GetDeleteFileCallback() {
+ return BindOnce(&DeleteFileHelper);
+}
+
+OnceCallback<void(const FilePath&)> GetDeletePathRecursivelyCallback() {
+ return BindOnce(IgnoreResult(&DeleteFileRecursively));
+}
+
int64_t ComputeDirectorySize(const FilePath& root_path) {
int64_t running_size = 0;
FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
diff --git a/chromium/base/files/file_util.h b/chromium/base/files/file_util.h
index 76bd98767f5..c9c2470942f 100644
--- a/chromium/base/files/file_util.h
+++ b/chromium/base/files/file_util.h
@@ -23,6 +23,7 @@
#endif
#include "base/base_export.h"
+#include "base/callback_forward.h"
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
@@ -34,7 +35,6 @@
#include "base/win/windows_types.h"
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
#include "base/file_descriptor_posix.h"
-#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#endif
@@ -59,33 +59,54 @@ BASE_EXPORT FilePath MakeAbsoluteFilePath(const FilePath& input);
BASE_EXPORT int64_t ComputeDirectorySize(const FilePath& root_path);
// Deletes the given path, whether it's a file or a directory.
+// If it's a directory, it's perfectly happy to delete all of the directory's
+// contents, but it will not recursively delete subdirectories and their
+// contents.
+// Returns true if successful, false otherwise. It is considered successful to
+// attempt to delete a file that does not exist.
+//
+// In POSIX environment and if |path| is a symbolic link, this deletes only
+// the symlink. (even if the symlink points to a non-existent file)
+BASE_EXPORT bool DeleteFile(const FilePath& path);
+
+// Deletes the given path, whether it's a file or a directory.
// If it's a directory, it's perfectly happy to delete all of the
-// directory's contents. Passing true to recursive deletes
-// subdirectories and their contents as well.
+// directory's contents, including subdirectories and their contents.
// Returns true if successful, false otherwise. It is considered successful
// to attempt to delete a file that does not exist.
//
// In POSIX environment and if |path| is a symbolic link, this deletes only
// the symlink. (even if the symlink points to a non-existent file)
//
-// WARNING: USING THIS WITH recursive==true IS EQUIVALENT
-// TO "rm -rf", SO USE WITH CAUTION.
-//
-// Note: The |recursive| parameter is in the process of being removed. Use
-// DeleteFileRecursively() instead. See https://crbug.com/1009837
-BASE_EXPORT bool DeleteFile(const FilePath& path, bool recursive);
+// WARNING: USING THIS EQUIVALENT TO "rm -rf", SO USE WITH CAUTION.
+// TODO(thestig): Rename to DeletePathRecursively().
+BASE_EXPORT bool DeleteFileRecursively(const FilePath& path);
+// DEPRECATED. Please use the functions immediately above.
+// https://crbug.com/1009837
+//
// Deletes the given path, whether it's a file or a directory.
// If it's a directory, it's perfectly happy to delete all of the
-// directory's contents, including subdirectories and their contents.
+// directory's contents. Passing true to recursively delete
+// subdirectories and their contents as well.
// Returns true if successful, false otherwise. It is considered successful
// to attempt to delete a file that does not exist.
//
// In POSIX environment and if |path| is a symbolic link, this deletes only
// the symlink. (even if the symlink points to a non-existent file)
//
-// WARNING: USING THIS EQUIVALENT TO "rm -rf", SO USE WITH CAUTION.
-BASE_EXPORT bool DeleteFileRecursively(const FilePath& path);
+// WARNING: USING THIS WITH recursive==true IS EQUIVALENT
+// TO "rm -rf", SO USE WITH CAUTION.
+BASE_EXPORT bool DeleteFile(const FilePath& path, bool recursive);
+
+// Simplified way to get a callback to do DeleteFile(path) and ignore the
+// DeleteFile() result.
+BASE_EXPORT OnceCallback<void(const FilePath&)> GetDeleteFileCallback();
+
+// Simplified way to get a callback to do DeleteFileRecursively(path) and ignore
+// the DeleteFileRecursively() result.
+BASE_EXPORT OnceCallback<void(const FilePath&)>
+GetDeletePathRecursivelyCallback();
#if defined(OS_WIN)
// Schedules to delete the given path, whether it's a file or a directory, until
@@ -223,6 +244,15 @@ BASE_EXPORT ScopedFD CreateAndOpenFdForTemporaryFileInDir(const FilePath& dir,
#if defined(OS_POSIX)
+// ReadFileToStringNonBlocking is identical to ReadFileToString except it
+// guarantees that it will not block. This guarantee is provided on POSIX by
+// opening the file as O_NONBLOCK. This variant should only be used on files
+// which are guaranteed not to block (such as kernel files). Or in situations
+// where a partial read would be acceptable because the backing store returned
+// EWOULDBLOCK.
+BASE_EXPORT bool ReadFileToStringNonBlocking(const base::FilePath& file,
+ std::string* ret);
+
// Creates a symbolic link at |symlink| pointing to |target|. Returns
// false on failure.
BASE_EXPORT bool CreateSymbolicLink(const FilePath& target,
diff --git a/chromium/base/files/file_util_posix.cc b/chromium/base/files/file_util_posix.cc
index 91514251d9c..dea1a945826 100644
--- a/chromium/base/files/file_util_posix.cc
+++ b/chromium/base/files/file_util_posix.cc
@@ -367,14 +367,18 @@ FilePath MakeAbsoluteFilePath(const FilePath& input) {
return FilePath(full_path);
}
-bool DeleteFile(const FilePath& path, bool recursive) {
- return DoDeleteFile(path, recursive);
+bool DeleteFile(const FilePath& path) {
+ return DoDeleteFile(path, /*recursive=*/false);
}
bool DeleteFileRecursively(const FilePath& path) {
return DoDeleteFile(path, /*recursive=*/true);
}
+bool DeleteFile(const FilePath& path, bool recursive) {
+ return DoDeleteFile(path, recursive);
+}
+
bool ReplaceFile(const FilePath& from_path,
const FilePath& to_path,
File::Error* error) {
@@ -736,6 +740,37 @@ bool CreateDirectoryAndGetError(const FilePath& full_path,
return true;
}
+// ReadFileToStringNonBlockingNonBlocking will read a file to a string. This
+// method should only be used on files which are known to be non-blocking such
+// as procfs or sysfs nodes. Additionally, the file is opened as O_NONBLOCK so
+// it WILL NOT block even if opened on a blocking file. It will return true if
+// the file read until EOF and it will return false otherwise, errno will remain
+// set on error conditions. |ret| will be populated with the contents of the
+// file.
+bool ReadFileToStringNonBlocking(const base::FilePath& file, std::string* ret) {
+ DCHECK(ret);
+ ret->clear();
+
+ base::ScopedFD fd(HANDLE_EINTR(
+ open(file.MaybeAsASCII().c_str(), O_CLOEXEC | O_NONBLOCK | O_RDONLY)));
+ if (!fd.is_valid()) {
+ return false;
+ }
+
+ ssize_t bytes_read = 0;
+ do {
+ char buf[4096];
+ bytes_read = HANDLE_EINTR(read(fd.get(), buf, sizeof(buf)));
+ if (bytes_read < 0) {
+ return false;
+ } else if (bytes_read > 0) {
+ ret->append(buf, bytes_read);
+ }
+ } while (bytes_read > 0);
+
+ return true;
+}
+
bool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) {
FilePath real_path_result = MakeAbsoluteFilePath(path);
if (real_path_result.empty())
diff --git a/chromium/base/files/file_util_unittest.cc b/chromium/base/files/file_util_unittest.cc
index 2ade5709855..701f8b4b6cd 100644
--- a/chromium/base/files/file_util_unittest.cc
+++ b/chromium/base/files/file_util_unittest.cc
@@ -28,6 +28,7 @@
#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
@@ -738,11 +739,11 @@ TEST_F(FileUtilTest, MakeLongFilePathTest) {
EXPECT_EQ(long_test_file, MakeLongFilePath(short_test_file));
// MakeLongFilePath should return empty path if file does not exist.
- EXPECT_TRUE(DeleteFile(short_test_file, false));
+ EXPECT_TRUE(DeleteFile(short_test_file));
EXPECT_TRUE(MakeLongFilePath(short_test_file).empty());
// MakeLongFilePath should return empty path if directory does not exist.
- EXPECT_TRUE(DeleteFile(short_test_dir, false));
+ EXPECT_TRUE(DeleteFile(short_test_dir));
EXPECT_TRUE(MakeLongFilePath(short_test_dir).empty());
}
@@ -850,7 +851,7 @@ TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) {
<< "Failed to create symlink.";
// Delete the symbolic link.
- EXPECT_TRUE(DeleteFile(file_link, false));
+ EXPECT_TRUE(DeleteFile(file_link));
// Make sure original file is not deleted.
EXPECT_FALSE(PathExists(file_link));
@@ -873,7 +874,7 @@ TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) {
EXPECT_FALSE(PathExists(file_link));
// Delete the symbolic link.
- EXPECT_TRUE(DeleteFile(file_link, false));
+ EXPECT_TRUE(DeleteFile(file_link));
// Make sure the symbolic link is deleted.
EXPECT_FALSE(IsLink(file_link));
@@ -941,7 +942,7 @@ TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) {
EXPECT_EQ(kDataSize, ReadFile(file_name, buffer, kDataSize));
// Delete the file.
- EXPECT_TRUE(DeleteFile(file_name, false));
+ EXPECT_TRUE(DeleteFile(file_name));
EXPECT_FALSE(PathExists(file_name));
}
@@ -981,7 +982,7 @@ TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) {
EXPECT_TRUE(PathIsWritable(file_name));
// Delete the file.
- EXPECT_TRUE(DeleteFile(file_name, false));
+ EXPECT_TRUE(DeleteFile(file_name));
EXPECT_FALSE(PathExists(file_name));
}
@@ -1291,7 +1292,7 @@ TEST_F(FileUtilTest, CopyFileExecutablePermission) {
expected_mode = 0600;
#endif
EXPECT_EQ(expected_mode, mode);
- ASSERT_TRUE(DeleteFile(dst, false));
+ ASSERT_TRUE(DeleteFile(dst));
ASSERT_TRUE(SetPosixFilePermissions(src, 0777));
ASSERT_TRUE(GetPosixFilePermissions(src, &mode));
@@ -1309,7 +1310,7 @@ TEST_F(FileUtilTest, CopyFileExecutablePermission) {
expected_mode = 0600;
#endif
EXPECT_EQ(expected_mode, mode);
- ASSERT_TRUE(DeleteFile(dst, false));
+ ASSERT_TRUE(DeleteFile(dst));
ASSERT_TRUE(SetPosixFilePermissions(src, 0400));
ASSERT_TRUE(GetPosixFilePermissions(src, &mode));
@@ -1403,7 +1404,7 @@ TEST_F(FileUtilTest, DeleteNonExistent) {
temp_dir_.GetPath().AppendASCII("bogus_file_dne.foobar");
ASSERT_FALSE(PathExists(non_existent));
- EXPECT_TRUE(DeleteFile(non_existent, false));
+ EXPECT_TRUE(DeleteFile(non_existent));
ASSERT_FALSE(PathExists(non_existent));
EXPECT_TRUE(DeleteFileRecursively(non_existent));
ASSERT_FALSE(PathExists(non_existent));
@@ -1414,7 +1415,7 @@ TEST_F(FileUtilTest, DeleteNonExistentWithNonExistentParent) {
non_existent = non_existent.AppendASCII("bogus_subdir");
ASSERT_FALSE(PathExists(non_existent));
- EXPECT_TRUE(DeleteFile(non_existent, false));
+ EXPECT_TRUE(DeleteFile(non_existent));
ASSERT_FALSE(PathExists(non_existent));
EXPECT_TRUE(DeleteFileRecursively(non_existent));
ASSERT_FALSE(PathExists(non_existent));
@@ -1427,7 +1428,7 @@ TEST_F(FileUtilTest, DeleteFile) {
ASSERT_TRUE(PathExists(file_name));
// Make sure it's deleted
- EXPECT_TRUE(DeleteFile(file_name, false));
+ EXPECT_TRUE(DeleteFile(file_name));
EXPECT_FALSE(PathExists(file_name));
// Test recursive case, create a new file
@@ -1461,7 +1462,7 @@ TEST_F(FileUtilTest, DeleteContentUri) {
ASSERT_TRUE(PathExists(uri_path));
// Try deleting the content URI.
- EXPECT_TRUE(DeleteFile(uri_path, false));
+ EXPECT_TRUE(DeleteFile(uri_path));
EXPECT_FALSE(PathExists(image_copy));
EXPECT_FALSE(PathExists(uri_path));
}
@@ -1487,7 +1488,7 @@ TEST_F(FileUtilTest, DeleteWildCard) {
directory_contents = directory_contents.Append(FPL("*"));
// Delete non-recursively and check that only the file is deleted
- EXPECT_TRUE(DeleteFile(directory_contents, false));
+ EXPECT_TRUE(DeleteFile(directory_contents));
EXPECT_FALSE(PathExists(file_name));
EXPECT_TRUE(PathExists(subdir_path));
@@ -1510,7 +1511,7 @@ TEST_F(FileUtilTest, DeleteNonExistantWildCard) {
directory_contents = directory_contents.Append(FPL("*"));
// Delete non-recursively and check nothing got deleted
- EXPECT_TRUE(DeleteFile(directory_contents, false));
+ EXPECT_TRUE(DeleteFile(directory_contents));
EXPECT_TRUE(PathExists(subdir_path));
// Delete recursively and check nothing got deleted
@@ -1540,11 +1541,11 @@ TEST_F(FileUtilTest, DeleteDirNonRecursive) {
ASSERT_TRUE(PathExists(subdir_path2));
// Delete non-recursively and check that the empty dir got deleted
- EXPECT_TRUE(DeleteFile(subdir_path2, false));
+ EXPECT_TRUE(DeleteFile(subdir_path2));
EXPECT_FALSE(PathExists(subdir_path2));
// Delete non-recursively and check that nothing got deleted
- EXPECT_FALSE(DeleteFile(test_subdir, false));
+ EXPECT_FALSE(DeleteFile(test_subdir));
EXPECT_TRUE(PathExists(test_subdir));
EXPECT_TRUE(PathExists(file_name));
EXPECT_TRUE(PathExists(subdir_path1));
@@ -1632,6 +1633,41 @@ TEST_F(FileUtilTest, DeleteDirRecursiveWithOpenFile) {
#endif
}
+#if defined(OS_LINUX)
+// This test will validate that files which would block when read result in a
+// failure on a call to ReadFileToStringNonBlocking. To accomplish this we will
+// use a named pipe because it appears as a file on disk and we can control how
+// much data is available to read. This allows us to simulate a file which would
+// block.
+TEST_F(FileUtilTest, TestNonBlockingFileReadLinux) {
+ FilePath fifo_path = temp_dir_.GetPath().Append(FPL("fifo"));
+ int res = mkfifo(fifo_path.MaybeAsASCII().c_str(),
+ S_IWUSR | S_IRUSR | S_IWGRP | S_IWGRP);
+ ASSERT_NE(res, -1);
+
+ base::ScopedFD fd(open(fifo_path.MaybeAsASCII().c_str(), O_RDWR));
+ ASSERT_TRUE(fd.is_valid());
+
+ std::string result;
+ // We will try to read when nothing is available on the fifo, the output
+ // string will be unmodified and it will fail with EWOULDBLOCK.
+ ASSERT_FALSE(ReadFileToStringNonBlocking(fifo_path, &result));
+ EXPECT_EQ(errno, EWOULDBLOCK);
+ EXPECT_TRUE(result.empty());
+
+ // Make a single byte available to read on the FIFO.
+ ASSERT_EQ(write(fd.get(), "a", 1), 1);
+
+ // Now the key part of the test we will call ReadFromFileNonBlocking which
+ // should fail, errno will be EWOULDBLOCK and the output string will contain
+ // the single 'a' byte.
+ ASSERT_FALSE(ReadFileToStringNonBlocking(fifo_path, &result));
+ EXPECT_EQ(errno, EWOULDBLOCK);
+ ASSERT_EQ(result.size(), 1u);
+ EXPECT_EQ(result[0], 'a');
+}
+#endif // defined(OS_LINUX)
+
TEST_F(FileUtilTest, MoveFileNew) {
// Create a file
FilePath file_name_from =
@@ -2223,7 +2259,7 @@ TEST_F(FileUtilTest, CopyDirectoryExclFileOverDanglingSymlink) {
dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
ASSERT_TRUE(PathExists(symlink_name_to));
- ASSERT_TRUE(DeleteFile(symlink_target, false));
+ ASSERT_TRUE(DeleteFile(symlink_target));
// Check that copying fails and that no file was created for the symlink's
// referent.
@@ -2258,7 +2294,7 @@ TEST_F(FileUtilTest, CopyDirectoryExclDirectoryOverDanglingSymlink) {
dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
ASSERT_TRUE(PathExists(symlink_name_to));
- ASSERT_TRUE(DeleteFile(symlink_target, false));
+ ASSERT_TRUE(DeleteFile(symlink_target));
// Check that copying fails and that no directory was created for the
// symlink's referent.
@@ -2533,7 +2569,7 @@ TEST_F(FileUtilTest, OpenFileNoInheritance) {
ASSERT_NO_FATAL_FAILURE(GetIsInheritable(file, &is_inheritable));
EXPECT_FALSE(is_inheritable);
}
- ASSERT_TRUE(DeleteFile(file_path, false));
+ ASSERT_TRUE(DeleteFile(file_path));
}
}
@@ -2565,7 +2601,7 @@ TEST_F(FileUtilTest, CreateTemporaryFileTest) {
for (int i = 0; i < 3; i++)
EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]);
for (const auto& i : temp_files)
- EXPECT_TRUE(DeleteFile(i, false));
+ EXPECT_TRUE(DeleteFile(i));
}
TEST_F(FileUtilTest, CreateAndOpenTemporaryStreamTest) {
@@ -2588,7 +2624,7 @@ TEST_F(FileUtilTest, CreateAndOpenTemporaryStreamTest) {
// Close and delete.
for (i = 0; i < 3; ++i) {
fps[i].reset();
- EXPECT_TRUE(DeleteFile(names[i], false));
+ EXPECT_TRUE(DeleteFile(names[i]));
}
}
@@ -2666,7 +2702,7 @@ TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
FilePath temp_dir;
ASSERT_TRUE(CreateNewTempDirectory(FilePath::StringType(), &temp_dir));
EXPECT_TRUE(PathExists(temp_dir));
- EXPECT_TRUE(DeleteFile(temp_dir, false));
+ EXPECT_TRUE(DeleteFile(temp_dir));
}
TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
@@ -2676,7 +2712,7 @@ TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
&new_dir));
EXPECT_TRUE(PathExists(new_dir));
EXPECT_TRUE(temp_dir_.GetPath().IsParent(new_dir));
- EXPECT_TRUE(DeleteFile(new_dir, false));
+ EXPECT_TRUE(DeleteFile(new_dir));
}
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -2836,7 +2872,7 @@ TEST_F(FileUtilTest, DetectDirectoryTest) {
CreateTextFile(test_path, L"test file");
EXPECT_TRUE(PathExists(test_path));
EXPECT_FALSE(DirectoryExists(test_path));
- EXPECT_TRUE(DeleteFile(test_path, false));
+ EXPECT_TRUE(DeleteFile(test_path));
EXPECT_TRUE(DeleteFileRecursively(test_root));
}
@@ -3105,7 +3141,7 @@ TEST_F(FileUtilTest, ReadFileToString) {
EXPECT_EQ(0u, data.length());
// Delete test file.
- EXPECT_TRUE(DeleteFile(file_path, false));
+ EXPECT_TRUE(DeleteFile(file_path));
data = "temp";
EXPECT_FALSE(ReadFileToString(file_path, &data));
@@ -4153,7 +4189,7 @@ TEST(FileUtilMultiThreadedTest, MAYBE_MultiThreadedTempFiles) {
EXPECT_EQ(content, output_file_contents);
- DeleteFile(output_filename, false);
+ DeleteFile(output_filename);
});
// Post tasks to each thread in a round-robin fashion to ensure as much
diff --git a/chromium/base/files/file_util_win.cc b/chromium/base/files/file_util_win.cc
index e0ac2598455..4399e1ae3bb 100644
--- a/chromium/base/files/file_util_win.cc
+++ b/chromium/base/files/file_util_win.cc
@@ -382,14 +382,18 @@ FilePath MakeAbsoluteFilePath(const FilePath& input) {
return FilePath(file_path);
}
-bool DeleteFile(const FilePath& path, bool recursive) {
- return DeleteFileAndRecordMetrics(path, recursive);
+bool DeleteFile(const FilePath& path) {
+ return DeleteFileAndRecordMetrics(path, /*recursive=*/false);
}
bool DeleteFileRecursively(const FilePath& path) {
return DeleteFileAndRecordMetrics(path, /*recursive=*/true);
}
+bool DeleteFile(const FilePath& path, bool recursive) {
+ return DeleteFileAndRecordMetrics(path, recursive);
+}
+
bool DeleteFileAfterReboot(const FilePath& path) {
ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
diff --git a/chromium/base/files/important_file_writer.cc b/chromium/base/files/important_file_writer.cc
index 79921df5c1f..c956fd351a1 100644
--- a/chromium/base/files/important_file_writer.cc
+++ b/chromium/base/files/important_file_writer.cc
@@ -30,6 +30,7 @@
#include "base/strings/string_util.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
+#include "base/threading/platform_thread.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
@@ -258,20 +259,32 @@ bool ImportantFileWriter::WriteFileAtomicallyImpl(const FilePath& path,
// The file must be closed for ReplaceFile to do its job, which opens up a
// race with other software that may open the temp file (e.g., an A/V scanner
- // doing its job without oplocks). Close as late as possible to improve the
- // chances that the other software will lose the race.
+ // doing its job without oplocks). Boost a background thread's priority on
+ // Windows and close as late as possible to improve the chances that the other
+ // software will lose the race.
+#if defined(OS_WIN)
+ const auto previous_priority = PlatformThread::GetCurrentThreadPriority();
+ const bool reset_priority = previous_priority <= ThreadPriority::NORMAL;
+ if (reset_priority)
+ PlatformThread::SetCurrentThreadPriority(ThreadPriority::DISPLAY);
+#endif // defined(OS_WIN)
tmp_file.Close();
- if (!ReplaceFile(tmp_file_path, path, &replace_file_error)) {
+ const bool result = ReplaceFile(tmp_file_path, path, &replace_file_error);
+#if defined(OS_WIN)
+ if (reset_priority)
+ PlatformThread::SetCurrentThreadPriority(previous_priority);
+#endif // defined(OS_WIN)
+
+ if (!result) {
UmaHistogramExactLinearWithSuffix("ImportantFile.FileRenameError",
histogram_suffix, -replace_file_error,
-File::FILE_ERROR_MAX);
LogFailure(path, histogram_suffix, FAILED_RENAMING,
"could not rename temporary file");
DeleteTmpFileWithRetry(File(), tmp_file_path, histogram_suffix);
- return false;
}
- return true;
+ return result;
}
ImportantFileWriter::ImportantFileWriter(
diff --git a/chromium/base/files/important_file_writer_cleaner_unittest.cc b/chromium/base/files/important_file_writer_cleaner_unittest.cc
index 6b0d6a5e746..d8121f44759 100644
--- a/chromium/base/files/important_file_writer_cleaner_unittest.cc
+++ b/chromium/base/files/important_file_writer_cleaner_unittest.cc
@@ -4,11 +4,11 @@
#include "base/files/important_file_writer_cleaner.h"
+#include "base/check.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/logging.h"
#include "base/optional.h"
#include "base/process/process.h"
#include "base/strings/stringprintf.h"
diff --git a/chromium/base/files/memory_mapped_file.cc b/chromium/base/files/memory_mapped_file.cc
index 6c8a0d9d581..30aefa1e639 100644
--- a/chromium/base/files/memory_mapped_file.cc
+++ b/chromium/base/files/memory_mapped_file.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/numerics/safe_math.h"
#include "base/system/sys_info.h"
#include "build/build_config.h"
diff --git a/chromium/base/files/memory_mapped_file_win.cc b/chromium/base/files/memory_mapped_file_win.cc
index cb43a879769..d5fece0e510 100644
--- a/chromium/base/files/memory_mapped_file_win.cc
+++ b/chromium/base/files/memory_mapped_file_win.cc
@@ -10,6 +10,7 @@
#include <limits>
#include "base/files/file_path.h"
+#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/pe_image.h"
diff --git a/chromium/base/files/scoped_file.h b/chromium/base/files/scoped_file.h
index 78fee9b7944..ee49fd7e655 100644
--- a/chromium/base/files/scoped_file.h
+++ b/chromium/base/files/scoped_file.h
@@ -10,7 +10,6 @@
#include <memory>
#include "base/base_export.h"
-#include "base/logging.h"
#include "base/scoped_generic.h"
#include "build/build_config.h"