blob: e7282f1eae8a5e5354713fe4278cd575016f5ae5 [file] [log] [blame]
[email protected]e7f009d2011-06-14 19:35:101// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]da34ae02009-09-22 20:41:202// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
pilgrim4af8c212014-09-05 17:30:155#include "storage/browser/database/vfs_backend.h"
[email protected]da34ae02009-09-22 20:41:206
avi5caf646e2015-12-21 21:21:507#include <stdint.h>
8
[email protected]57999812013-02-24 05:40:529#include "base/files/file_path.h"
thestig22dfc4012014-09-05 08:29:4410#include "base/files/file_util.h"
[email protected]3c5ed2c2009-11-13 01:30:4511#include "base/logging.h"
[email protected]e33cba42010-08-18 23:37:0312#include "third_party/sqlite/sqlite3.h"
[email protected]da34ae02009-09-22 20:41:2013
[email protected]cd501a72014-08-22 19:58:3114namespace storage {
[email protected]da34ae02009-09-22 20:41:2015
[email protected]a3703dd2010-02-11 17:46:1316static const int kFileTypeMask = 0x00007F00;
17
18// static
[email protected]a3703dd2010-02-11 17:46:1319bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) {
[email protected]2f312ab2010-04-21 07:17:4120 return (desired_flags & SQLITE_OPEN_READWRITE) != 0;
[email protected]a3703dd2010-02-11 17:46:1321}
22
23// static
[email protected]3c5ed2c2009-11-13 01:30:4524bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) {
[email protected]a3703dd2010-02-11 17:46:1325 const int file_type = desired_flags & kFileTypeMask;
[email protected]da34ae02009-09-22 20:41:2026 const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0;
27 const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0;
28 const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0;
29 const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0;
30 const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0;
31
[email protected]b5be3f532009-10-24 01:28:3932 // All files should be opened either read-write or read-only, but not both.
33 if (is_read_only == is_read_write)
[email protected]da34ae02009-09-22 20:41:2034 return false;
[email protected]da34ae02009-09-22 20:41:2035
[email protected]b5be3f532009-10-24 01:28:3936 // If a new file is created, it must also be writable.
37 if (is_create && !is_read_write)
[email protected]da34ae02009-09-22 20:41:2038 return false;
[email protected]da34ae02009-09-22 20:41:2039
[email protected]b5be3f532009-10-24 01:28:3940 // If we're accessing an existing file, we cannot give exclusive access, and
41 // we can't delete it.
[email protected]fe615f32010-06-13 09:08:4142 // Normally, we'd also check that 'is_delete' is false for a main DB, main
43 // journal or master journal file; however, when in incognito mode, we use
44 // the SQLITE_OPEN_DELETEONCLOSE flag when opening those files too and keep
45 // an open handle to them for as long as the incognito profile is around.
[email protected]b5be3f532009-10-24 01:28:3946 if ((is_exclusive || is_delete) && !is_create)
[email protected]da34ae02009-09-22 20:41:2047 return false;
[email protected]da34ae02009-09-22 20:41:2048
[email protected]da34ae02009-09-22 20:41:2049 // Make sure we're opening the DB directory or that a file type is set.
[email protected]b5be3f532009-10-24 01:28:3950 return (file_type == SQLITE_OPEN_MAIN_DB) ||
51 (file_type == SQLITE_OPEN_TEMP_DB) ||
52 (file_type == SQLITE_OPEN_MAIN_JOURNAL) ||
53 (file_type == SQLITE_OPEN_TEMP_JOURNAL) ||
54 (file_type == SQLITE_OPEN_SUBJOURNAL) ||
55 (file_type == SQLITE_OPEN_MASTER_JOURNAL) ||
56 (file_type == SQLITE_OPEN_TRANSIENT_DB);
[email protected]da34ae02009-09-22 20:41:2057}
58
[email protected]a3703dd2010-02-11 17:46:1359// static
[email protected]382aa7e2014-03-28 01:13:3760base::File VfsBackend::OpenFile(const base::FilePath& file_path,
61 int desired_flags) {
[email protected]3c5ed2c2009-11-13 01:30:4562 DCHECK(!file_path.empty());
63
[email protected]da34ae02009-09-22 20:41:2064 // Verify the flags for consistency and create the database
65 // directory if it doesn't exist.
[email protected]3c5ed2c2009-11-13 01:30:4566 if (!OpenFileFlagsAreConsistent(desired_flags) ||
[email protected]382aa7e2014-03-28 01:13:3767 !base::CreateDirectory(file_path.DirName())) {
68 return base::File();
69 }
[email protected]da34ae02009-09-22 20:41:2070
[email protected]c93efc7c52009-10-29 19:58:3071 int flags = 0;
[email protected]382aa7e2014-03-28 01:13:3772 flags |= base::File::FLAG_READ;
[email protected]c93efc7c52009-10-29 19:58:3073 if (desired_flags & SQLITE_OPEN_READWRITE)
[email protected]382aa7e2014-03-28 01:13:3774 flags |= base::File::FLAG_WRITE;
[email protected]da34ae02009-09-22 20:41:2075
[email protected]382aa7e2014-03-28 01:13:3776 if (!(desired_flags & SQLITE_OPEN_MAIN_DB))
77 flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;
[email protected]da34ae02009-09-22 20:41:2078
[email protected]c93efc7c52009-10-29 19:58:3079 flags |= ((desired_flags & SQLITE_OPEN_CREATE) ?
[email protected]382aa7e2014-03-28 01:13:3780 base::File::FLAG_OPEN_ALWAYS : base::File::FLAG_OPEN);
[email protected]da34ae02009-09-22 20:41:2081
[email protected]382aa7e2014-03-28 01:13:3782 if (desired_flags & SQLITE_OPEN_EXCLUSIVE)
83 flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;
[email protected]da34ae02009-09-22 20:41:2084
[email protected]c93efc7c52009-10-29 19:58:3085 if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
[email protected]382aa7e2014-03-28 01:13:3786 flags |= base::File::FLAG_TEMPORARY | base::File::FLAG_HIDDEN |
87 base::File::FLAG_DELETE_ON_CLOSE;
[email protected]c93efc7c52009-10-29 19:58:3088 }
[email protected]da34ae02009-09-22 20:41:2089
[email protected]800ad562011-07-08 08:00:5090 // This flag will allow us to delete the file later on from the browser
91 // process.
[email protected]382aa7e2014-03-28 01:13:3792 flags |= base::File::FLAG_SHARE_DELETE;
[email protected]800ad562011-07-08 08:00:5093
[email protected]c93efc7c52009-10-29 19:58:3094 // Try to open/create the DB file.
[email protected]382aa7e2014-03-28 01:13:3795 return base::File(file_path, flags);
[email protected]da34ae02009-09-22 20:41:2096}
97
[email protected]a3703dd2010-02-11 17:46:1398// static
[email protected]382aa7e2014-03-28 01:13:3799base::File VfsBackend::OpenTempFileInDirectory(const base::FilePath& dir_path,
100 int desired_flags) {
[email protected]3c5ed2c2009-11-13 01:30:45101 // We should be able to delete temp files when they're closed
102 // and create them as needed
103 if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) ||
104 !(desired_flags & SQLITE_OPEN_CREATE)) {
[email protected]382aa7e2014-03-28 01:13:37105 return base::File();
[email protected]3c5ed2c2009-11-13 01:30:45106 }
107
108 // Get a unique temp file name in the database directory.
[email protected]a3ef4832013-02-02 05:12:33109 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:52110 if (!base::CreateTemporaryFileInDir(dir_path, &temp_file_path))
[email protected]382aa7e2014-03-28 01:13:37111 return base::File();
[email protected]3c5ed2c2009-11-13 01:30:45112
[email protected]382aa7e2014-03-28 01:13:37113 return OpenFile(temp_file_path, desired_flags);
[email protected]3c5ed2c2009-11-13 01:30:45114}
115
[email protected]a3703dd2010-02-11 17:46:13116// static
[email protected]a3ef4832013-02-02 05:12:33117int VfsBackend::DeleteFile(const base::FilePath& file_path, bool sync_dir) {
[email protected]7567484142013-07-11 17:36:07118 if (!base::PathExists(file_path))
[email protected]da34ae02009-09-22 20:41:20119 return SQLITE_OK;
[email protected]dd3aa792013-07-16 19:10:23120 if (!base::DeleteFile(file_path, false))
[email protected]da34ae02009-09-22 20:41:20121 return SQLITE_IOERR_DELETE;
[email protected]da34ae02009-09-22 20:41:20122
123 int error_code = SQLITE_OK;
124#if defined(OS_POSIX)
125 if (sync_dir) {
[email protected]382aa7e2014-03-28 01:13:37126 base::File dir(file_path.DirName(), base::File::FLAG_READ);
127 if (dir.IsValid()) {
128 if (!dir.Flush())
[email protected]da34ae02009-09-22 20:41:20129 error_code = SQLITE_IOERR_DIR_FSYNC;
[email protected]382aa7e2014-03-28 01:13:37130 } else {
131 error_code = SQLITE_CANTOPEN;
[email protected]da34ae02009-09-22 20:41:20132 }
133 }
134#endif
135 return error_code;
136}
137
[email protected]a3703dd2010-02-11 17:46:13138// static
avi5caf646e2015-12-21 21:21:50139uint32_t VfsBackend::GetFileAttributes(const base::FilePath& file_path) {
[email protected]da34ae02009-09-22 20:41:20140#if defined(OS_WIN)
avi5caf646e2015-12-21 21:21:50141 uint32_t attributes = ::GetFileAttributes(file_path.value().c_str());
[email protected]da34ae02009-09-22 20:41:20142#elif defined(OS_POSIX)
avi5caf646e2015-12-21 21:21:50143 uint32_t attributes = 0;
[email protected]3c5ed2c2009-11-13 01:30:45144 if (!access(file_path.value().c_str(), R_OK))
avi5caf646e2015-12-21 21:21:50145 attributes |= static_cast<uint32_t>(R_OK);
[email protected]3c5ed2c2009-11-13 01:30:45146 if (!access(file_path.value().c_str(), W_OK))
avi5caf646e2015-12-21 21:21:50147 attributes |= static_cast<uint32_t>(W_OK);
[email protected]b5be3f532009-10-24 01:28:39148 if (!attributes)
[email protected]da34ae02009-09-22 20:41:20149 attributes = -1;
[email protected]da34ae02009-09-22 20:41:20150#endif
151 return attributes;
152}
153
[email protected]a3703dd2010-02-11 17:46:13154// static
avi5caf646e2015-12-21 21:21:50155int64_t VfsBackend::GetFileSize(const base::FilePath& file_path) {
156 int64_t size = 0;
[email protected]56285702013-12-04 18:22:49157 return (base::GetFileSize(file_path, &size) ? size : 0);
[email protected]da34ae02009-09-22 20:41:20158}
159
shess10ce3cc2015-04-06 18:52:16160// static
avi5caf646e2015-12-21 21:21:50161bool VfsBackend::SetFileSize(const base::FilePath& file_path, int64_t size) {
shess10ce3cc2015-04-06 18:52:16162 int flags = 0;
163 flags |= base::File::FLAG_READ;
164 flags |= base::File::FLAG_WRITE;
165 flags |= base::File::FLAG_OPEN;
166 base::File file = base::File(file_path, flags);
167 if (!file.IsValid())
168 return false;
169 return file.SetLength(size);
170}
171
[email protected]cd501a72014-08-22 19:58:31172} // namespace storage