15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deny |permission| on the file |path|. 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool DenyFilePermission(const FilePath& path, mode_t permission) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct stat stat_buf; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stat(path.value().c_str(), &stat_buf) != 0) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stat_buf.st_mode &= ~permission; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = HANDLE_EINTR(chmod(path.value().c_str(), stat_buf.st_mode)); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv == 0; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets a blob indicating the permission information for |path|. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |length| is the length of the blob. Zero on failure. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the blob pointer, or NULL on failure. 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void* GetPermissionInfo(const FilePath& path, size_t* length) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(length); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct stat stat_buf; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stat(path.value().c_str(), &stat_buf) != 0) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = sizeof(mode_t); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode_t* mode = new mode_t; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mode = stat_buf.st_mode & ~S_IFMT; // Filter out file/path kind. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mode; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Restores the permission information for |path|, given the blob retrieved 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using |GetPermissionInfo()|. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |info| is the pointer to the blob. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |length| is the length of the blob. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Either |info| or |length| may be NULL/0, in which case nothing happens. 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info || (length == 0)) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(sizeof(mode_t), length); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode_t* mode = reinterpret_cast<mode_t*>(info); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = HANDLE_EINTR(chmod(path.value().c_str(), *mode)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete mode; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv == 0; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool DieFileDie(const FilePath& file, bool recurse) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no need to workaround Windows problems on POSIX. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just pass-through. 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return DeleteFile(file, recurse); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_LINUX) && !defined(OS_MACOSX) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool EvictFileFromSystemCache(const FilePath& file) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There doesn't seem to be a POSIX way to cool the disk cache. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool MakeFileUnreadable(const FilePath& path) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool MakeFileUnwritable(const FilePath& path) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)FilePermissionRestorer::FilePermissionRestorer(const FilePath& path) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : path_(path), info_(NULL), length_(0) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ = GetPermissionInfo(path_, &length_); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_ != NULL); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0u, length_); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)FilePermissionRestorer::~FilePermissionRestorer() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RestorePermissionInfo(path_, info_, length_)) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace base 109