• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/test/test_file_util.h"
6 
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stddef.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12 
13 #include <string>
14 
15 #include "base/check_op.h"
16 #include "base/files/file.h"
17 #include "base/files/file_util.h"
18 #include "base/notreached.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "build/build_config.h"
22 
23 namespace base {
24 
25 namespace {
26 
27 // Deny |permission| on the file |path|.
DenyFilePermission(const FilePath & path,mode_t permission)28 bool DenyFilePermission(const FilePath& path, mode_t permission) {
29   stat_wrapper_t stat_buf;
30   if (File::Stat(path.value().c_str(), &stat_buf) != 0)
31     return false;
32   stat_buf.st_mode &= ~permission;
33 
34   int rv = HANDLE_EINTR(chmod(path.value().c_str(), stat_buf.st_mode));
35   return rv == 0;
36 }
37 
38 // Gets a blob indicating the permission information for |path|.
39 // |length| is the length of the blob.  Zero on failure.
40 // Returns the blob pointer, or NULL on failure.
GetPermissionInfo(const FilePath & path,size_t * length)41 void* GetPermissionInfo(const FilePath& path, size_t* length) {
42   DCHECK(length);
43   *length = 0;
44 
45   stat_wrapper_t stat_buf;
46   if (File::Stat(path.value().c_str(), &stat_buf) != 0)
47     return nullptr;
48 
49   *length = sizeof(mode_t);
50   mode_t* mode = new mode_t;
51   *mode = stat_buf.st_mode & ~S_IFMT;  // Filter out file/path kind.
52 
53   return mode;
54 }
55 
56 // Restores the permission information for |path|, given the blob retrieved
57 // using |GetPermissionInfo()|.
58 // |info| is the pointer to the blob.
59 // |length| is the length of the blob.
60 // Either |info| or |length| may be NULL/0, in which case nothing happens.
RestorePermissionInfo(const FilePath & path,void * info,size_t length)61 bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) {
62   if (!info || (length == 0))
63     return false;
64 
65   DCHECK_EQ(sizeof(mode_t), length);
66   mode_t* mode = reinterpret_cast<mode_t*>(info);
67 
68   int rv = HANDLE_EINTR(chmod(path.value().c_str(), *mode));
69 
70   delete mode;
71 
72   return rv == 0;
73 }
74 
75 }  // namespace
76 
DieFileDie(const FilePath & file,bool recurse)77 bool DieFileDie(const FilePath& file, bool recurse) {
78   // There is no need to workaround Windows problems on POSIX.
79   // Just pass-through.
80   if (recurse)
81     return DeletePathRecursively(file);
82   return DeleteFile(file);
83 }
84 
SyncPageCacheToDisk()85 void SyncPageCacheToDisk() {
86   // On Linux (and Android) the sync(2) call waits for I/O completions.
87   sync();
88 }
89 
90 #if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_APPLE) && \
91     !BUILDFLAG(IS_ANDROID)
EvictFileFromSystemCache(const FilePath & file)92 bool EvictFileFromSystemCache(const FilePath& file) {
93   // There doesn't seem to be a POSIX way to cool the disk cache.
94   NOTIMPLEMENTED();
95   return false;
96 }
97 #endif
98 
MakeFileUnreadable(const FilePath & path)99 bool MakeFileUnreadable(const FilePath& path) {
100   return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH);
101 }
102 
MakeFileUnwritable(const FilePath & path)103 bool MakeFileUnwritable(const FilePath& path) {
104   return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH);
105 }
106 
FilePermissionRestorer(const FilePath & path)107 FilePermissionRestorer::FilePermissionRestorer(const FilePath& path)
108     : path_(path), info_(nullptr), length_(0) {
109   info_ = GetPermissionInfo(path_, &length_);
110   DCHECK(info_ != nullptr);
111   DCHECK_NE(0u, length_);
112 }
113 
~FilePermissionRestorer()114 FilePermissionRestorer::~FilePermissionRestorer() {
115   if (!RestorePermissionInfo(path_, info_, length_))
116     NOTREACHED();
117 }
118 
119 }  // namespace base
120