test_file_util_posix.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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