Home | History | Annotate | Download | only in test
      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