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