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 <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 
     20 namespace base {
     21 
     22 namespace {
     23 
     24 // Deny |permission| on the file |path|.
     25 bool 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.
     38 void* 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.
     58 bool 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 
     74 bool 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)
     81 bool 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 
     88 bool MakeFileUnreadable(const FilePath& path) {
     89   return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH);
     90 }
     91 
     92 bool MakeFileUnwritable(const FilePath& path) {
     93   return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH);
     94 }
     95 
     96 FilePermissionRestorer::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 
    103 FilePermissionRestorer::~FilePermissionRestorer() {
    104   if (!RestorePermissionInfo(path_, info_, length_))
    105     NOTREACHED();
    106 }
    107 
    108 }  // namespace base
    109