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/file_util.h" 15#include "base/files/file_path.h" 16#include "base/logging.h" 17#include "base/strings/string_util.h" 18#include "base/strings/utf_string_conversions.h" 19 20using base::MakeAbsoluteFilePath; 21 22namespace file_util { 23 24namespace { 25 26// Deny |permission| on the file |path|. 27bool DenyFilePermission(const base::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. 40void* GetPermissionInfo(const base::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. 60bool RestorePermissionInfo(const base::FilePath& path, 61 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 77bool DieFileDie(const base::FilePath& file, bool recurse) { 78 // There is no need to workaround Windows problems on POSIX. 79 // Just pass-through. 80 return base::DeleteFile(file, recurse); 81} 82 83#if !defined(OS_LINUX) && !defined(OS_MACOSX) 84bool EvictFileFromSystemCache(const base::FilePath& file) { 85 // There doesn't seem to be a POSIX way to cool the disk cache. 86 NOTIMPLEMENTED(); 87 return false; 88} 89#endif 90 91std::wstring FilePathAsWString(const base::FilePath& path) { 92 return UTF8ToWide(path.value()); 93} 94base::FilePath WStringAsFilePath(const std::wstring& path) { 95 return base::FilePath(WideToUTF8(path)); 96} 97 98bool MakeFileUnreadable(const base::FilePath& path) { 99 return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH); 100} 101 102bool MakeFileUnwritable(const base::FilePath& path) { 103 return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH); 104} 105 106PermissionRestorer::PermissionRestorer(const base::FilePath& path) 107 : path_(path), info_(NULL), length_(0) { 108 info_ = GetPermissionInfo(path_, &length_); 109 DCHECK(info_ != NULL); 110 DCHECK_NE(0u, length_); 111} 112 113PermissionRestorer::~PermissionRestorer() { 114 if (!RestorePermissionInfo(path_, info_, length_)) 115 NOTREACHED(); 116} 117 118} // namespace file_util 119