1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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/stat.h> 11 #include <sys/types.h> 12 13 #include <string> 14 15 #include "base/files/file_path.h" 16 #include "base/files/file_util.h" 17 #include "base/logging.h" 18 #include "base/strings/string_util.h" 19 #include "base/strings/utf_string_conversions.h" 20 #include "build/build_config.h" 21 22 namespace base { 23 24 namespace { 25 26 // Deny |permission| on the file |path|. 27 bool DenyFilePermission(const FilePath& path, mode_t permission) { 28 struct stat stat_buf; 29 if (stat(path.value().c_str(), &stat_buf) != 0) 30 return false; 31 stat_buf.st_mode &= ~permission; 32 33 int rv = HANDLE_EINTR(chmod(path.value().c_str(), stat_buf.st_mode)); 34 return rv == 0; 35 } 36 37 // Gets a blob indicating the permission information for |path|. 38 // |length| is the length of the blob. Zero on failure. 39 // Returns the blob pointer, or NULL on failure. 40 void* GetPermissionInfo(const FilePath& path, size_t* length) { 41 DCHECK(length); 42 *length = 0; 43 44 struct stat stat_buf; 45 if (stat(path.value().c_str(), &stat_buf) != 0) 46 return NULL; 47 48 *length = sizeof(mode_t); 49 mode_t* mode = new mode_t; 50 *mode = stat_buf.st_mode & ~S_IFMT; // Filter out file/path kind. 51 52 return mode; 53 } 54 55 // Restores the permission information for |path|, given the blob retrieved 56 // using |GetPermissionInfo()|. 57 // |info| is the pointer to the blob. 58 // |length| is the length of the blob. 59 // Either |info| or |length| may be NULL/0, in which case nothing happens. 60 bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) { 61 if (!info || (length == 0)) 62 return false; 63 64 DCHECK_EQ(sizeof(mode_t), length); 65 mode_t* mode = reinterpret_cast<mode_t*>(info); 66 67 int rv = HANDLE_EINTR(chmod(path.value().c_str(), *mode)); 68 69 delete mode; 70 71 return rv == 0; 72 } 73 74 } // namespace 75 76 bool DieFileDie(const FilePath& file, bool recurse) { 77 // There is no need to workaround Windows problems on POSIX. 78 // Just pass-through. 79 return DeleteFile(file, recurse); 80 } 81 82 #if !defined(OS_LINUX) && !defined(OS_MACOSX) 83 bool EvictFileFromSystemCache(const FilePath& file) { 84 // There doesn't seem to be a POSIX way to cool the disk cache. 85 NOTIMPLEMENTED(); 86 return false; 87 } 88 #endif 89 90 bool MakeFileUnreadable(const FilePath& path) { 91 return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH); 92 } 93 94 bool MakeFileUnwritable(const FilePath& path) { 95 return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH); 96 } 97 98 FilePermissionRestorer::FilePermissionRestorer(const FilePath& path) 99 : path_(path), info_(NULL), length_(0) { 100 info_ = GetPermissionInfo(path_, &length_); 101 DCHECK(info_ != NULL); 102 DCHECK_NE(0u, length_); 103 } 104 105 FilePermissionRestorer::~FilePermissionRestorer() { 106 if (!RestorePermissionInfo(path_, info_, length_)) 107 NOTREACHED(); 108 } 109 110 } // namespace base 111