test_file_util_posix.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 base {
23
24namespace {
25
26// Deny |permission| on the file |path|.
27bool 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.
40void* 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.
60bool 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
76bool 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)
83bool 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}  // namespace base
91
92namespace file_util {
93
94using base::DenyFilePermission;
95using base::GetPermissionInfo;
96using base::RestorePermissionInfo;
97
98std::wstring FilePathAsWString(const base::FilePath& path) {
99  return base::UTF8ToWide(path.value());
100}
101base::FilePath WStringAsFilePath(const std::wstring& path) {
102  return base::FilePath(base::WideToUTF8(path));
103}
104
105bool MakeFileUnreadable(const base::FilePath& path) {
106  return DenyFilePermission(path, S_IRUSR | S_IRGRP | S_IROTH);
107}
108
109bool MakeFileUnwritable(const base::FilePath& path) {
110  return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH);
111}
112
113PermissionRestorer::PermissionRestorer(const base::FilePath& path)
114    : path_(path), info_(NULL), length_(0) {
115  info_ = GetPermissionInfo(path_, &length_);
116  DCHECK(info_ != NULL);
117  DCHECK_NE(0u, length_);
118}
119
120PermissionRestorer::~PermissionRestorer() {
121  if (!RestorePermissionInfo(path_, info_, length_))
122    NOTREACHED();
123}
124
125}  // namespace file_util
126