blob: 3f51c2e2e7dd3bfd07a7d5dfeb722ff5b1645daa [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
[email protected]08b1f75f2013-05-22 22:02:385#include "webkit/browser/database/vfs_backend.h"
[email protected]da34ae02009-09-22 20:41:206
[email protected]da34ae02009-09-22 20:41:207#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:528#include "base/files/file_path.h"
[email protected]3c5ed2c2009-11-13 01:30:459#include "base/logging.h"
[email protected]e33cba42010-08-18 23:37:0310#include "third_party/sqlite/sqlite3.h"
[email protected]da34ae02009-09-22 20:41:2011
12namespace webkit_database {
13
[email protected]a3703dd2010-02-11 17:46:1314static const int kFileTypeMask = 0x00007F00;
15
16// static
[email protected]a3703dd2010-02-11 17:46:1317bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) {
[email protected]2f312ab2010-04-21 07:17:4118 return (desired_flags & SQLITE_OPEN_READWRITE) != 0;
[email protected]a3703dd2010-02-11 17:46:1319}
20
21// static
[email protected]3c5ed2c2009-11-13 01:30:4522bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) {
[email protected]a3703dd2010-02-11 17:46:1323 const int file_type = desired_flags & kFileTypeMask;
[email protected]da34ae02009-09-22 20:41:2024 const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0;
25 const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0;
26 const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0;
27 const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0;
28 const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0;
29
[email protected]b5be3f532009-10-24 01:28:3930 // All files should be opened either read-write or read-only, but not both.
31 if (is_read_only == is_read_write)
[email protected]da34ae02009-09-22 20:41:2032 return false;
[email protected]da34ae02009-09-22 20:41:2033
[email protected]b5be3f532009-10-24 01:28:3934 // If a new file is created, it must also be writable.
35 if (is_create && !is_read_write)
[email protected]da34ae02009-09-22 20:41:2036 return false;
[email protected]da34ae02009-09-22 20:41:2037
[email protected]b5be3f532009-10-24 01:28:3938 // If we're accessing an existing file, we cannot give exclusive access, and
39 // we can't delete it.
[email protected]fe615f32010-06-13 09:08:4140 // Normally, we'd also check that 'is_delete' is false for a main DB, main
41 // journal or master journal file; however, when in incognito mode, we use
42 // the SQLITE_OPEN_DELETEONCLOSE flag when opening those files too and keep
43 // an open handle to them for as long as the incognito profile is around.
[email protected]b5be3f532009-10-24 01:28:3944 if ((is_exclusive || is_delete) && !is_create)
[email protected]da34ae02009-09-22 20:41:2045 return false;
[email protected]da34ae02009-09-22 20:41:2046
[email protected]da34ae02009-09-22 20:41:2047 // Make sure we're opening the DB directory or that a file type is set.
[email protected]b5be3f532009-10-24 01:28:3948 return (file_type == SQLITE_OPEN_MAIN_DB) ||
49 (file_type == SQLITE_OPEN_TEMP_DB) ||
50 (file_type == SQLITE_OPEN_MAIN_JOURNAL) ||
51 (file_type == SQLITE_OPEN_TEMP_JOURNAL) ||
52 (file_type == SQLITE_OPEN_SUBJOURNAL) ||
53 (file_type == SQLITE_OPEN_MASTER_JOURNAL) ||
54 (file_type == SQLITE_OPEN_TRANSIENT_DB);
[email protected]da34ae02009-09-22 20:41:2055}
56
[email protected]a3703dd2010-02-11 17:46:1357// static
[email protected]a3ef4832013-02-02 05:12:3358void VfsBackend::OpenFile(const base::FilePath& file_path,
[email protected]b5be3f532009-10-24 01:28:3959 int desired_flags,
[email protected]fe615f32010-06-13 09:08:4160 base::PlatformFile* file_handle) {
[email protected]3c5ed2c2009-11-13 01:30:4561 DCHECK(!file_path.empty());
62
[email protected]da34ae02009-09-22 20:41:2063 // Verify the flags for consistency and create the database
64 // directory if it doesn't exist.
[email protected]3c5ed2c2009-11-13 01:30:4565 if (!OpenFileFlagsAreConsistent(desired_flags) ||
[email protected]426d1c92013-12-03 20:08:5466 !base::CreateDirectory(file_path.DirName()))
[email protected]c93efc7c52009-10-29 19:58:3067 return;
[email protected]da34ae02009-09-22 20:41:2068
[email protected]c93efc7c52009-10-29 19:58:3069 int flags = 0;
70 flags |= base::PLATFORM_FILE_READ;
71 if (desired_flags & SQLITE_OPEN_READWRITE)
72 flags |= base::PLATFORM_FILE_WRITE;
[email protected]da34ae02009-09-22 20:41:2073
[email protected]c93efc7c52009-10-29 19:58:3074 if (!(desired_flags & SQLITE_OPEN_MAIN_DB)) {
75 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
76 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
77 }
[email protected]da34ae02009-09-22 20:41:2078
[email protected]c93efc7c52009-10-29 19:58:3079 flags |= ((desired_flags & SQLITE_OPEN_CREATE) ?
80 base::PLATFORM_FILE_OPEN_ALWAYS : base::PLATFORM_FILE_OPEN);
[email protected]da34ae02009-09-22 20:41:2081
[email protected]c93efc7c52009-10-29 19:58:3082 if (desired_flags & SQLITE_OPEN_EXCLUSIVE) {
83 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
84 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
85 }
[email protected]da34ae02009-09-22 20:41:2086
[email protected]c93efc7c52009-10-29 19:58:3087 if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
88 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN |
89 base::PLATFORM_FILE_DELETE_ON_CLOSE;
90 }
[email protected]da34ae02009-09-22 20:41:2091
[email protected]800ad562011-07-08 08:00:5092 // This flag will allow us to delete the file later on from the browser
93 // process.
94 flags |= base::PLATFORM_FILE_SHARE_DELETE;
95
[email protected]c93efc7c52009-10-29 19:58:3096 // Try to open/create the DB file.
[email protected]fe615f32010-06-13 09:08:4197 *file_handle =
[email protected]ed65fec2010-08-31 19:30:2798 base::CreatePlatformFile(file_path, flags, NULL, NULL);
[email protected]da34ae02009-09-22 20:41:2099}
100
[email protected]a3703dd2010-02-11 17:46:13101// static
[email protected]3c5ed2c2009-11-13 01:30:45102void VfsBackend::OpenTempFileInDirectory(
[email protected]a3ef4832013-02-02 05:12:33103 const base::FilePath& dir_path,
[email protected]3c5ed2c2009-11-13 01:30:45104 int desired_flags,
[email protected]fe615f32010-06-13 09:08:41105 base::PlatformFile* file_handle) {
[email protected]3c5ed2c2009-11-13 01:30:45106 // We should be able to delete temp files when they're closed
107 // and create them as needed
108 if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) ||
109 !(desired_flags & SQLITE_OPEN_CREATE)) {
110 return;
111 }
112
113 // Get a unique temp file name in the database directory.
[email protected]a3ef4832013-02-02 05:12:33114 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:52115 if (!base::CreateTemporaryFileInDir(dir_path, &temp_file_path))
[email protected]3c5ed2c2009-11-13 01:30:45116 return;
117
[email protected]fe615f32010-06-13 09:08:41118 OpenFile(temp_file_path, desired_flags, file_handle);
[email protected]3c5ed2c2009-11-13 01:30:45119}
120
[email protected]a3703dd2010-02-11 17:46:13121// static
[email protected]a3ef4832013-02-02 05:12:33122int VfsBackend::DeleteFile(const base::FilePath& file_path, bool sync_dir) {
[email protected]7567484142013-07-11 17:36:07123 if (!base::PathExists(file_path))
[email protected]da34ae02009-09-22 20:41:20124 return SQLITE_OK;
[email protected]dd3aa792013-07-16 19:10:23125 if (!base::DeleteFile(file_path, false))
[email protected]da34ae02009-09-22 20:41:20126 return SQLITE_IOERR_DELETE;
[email protected]da34ae02009-09-22 20:41:20127
128 int error_code = SQLITE_OK;
129#if defined(OS_POSIX)
130 if (sync_dir) {
131 base::PlatformFile dir_fd = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27132 file_path.DirName(), base::PLATFORM_FILE_READ, NULL, NULL);
[email protected]da34ae02009-09-22 20:41:20133 if (dir_fd == base::kInvalidPlatformFileValue) {
134 error_code = SQLITE_CANTOPEN;
135 } else {
[email protected]b5be3f532009-10-24 01:28:39136 if (fsync(dir_fd))
[email protected]da34ae02009-09-22 20:41:20137 error_code = SQLITE_IOERR_DIR_FSYNC;
[email protected]da34ae02009-09-22 20:41:20138 base::ClosePlatformFile(dir_fd);
139 }
140 }
141#endif
142 return error_code;
143}
144
[email protected]a3703dd2010-02-11 17:46:13145// static
[email protected]a3ef4832013-02-02 05:12:33146uint32 VfsBackend::GetFileAttributes(const base::FilePath& file_path) {
[email protected]da34ae02009-09-22 20:41:20147#if defined(OS_WIN)
[email protected]3c5ed2c2009-11-13 01:30:45148 uint32 attributes = ::GetFileAttributes(file_path.value().c_str());
[email protected]da34ae02009-09-22 20:41:20149#elif defined(OS_POSIX)
150 uint32 attributes = 0;
[email protected]3c5ed2c2009-11-13 01:30:45151 if (!access(file_path.value().c_str(), R_OK))
[email protected]da34ae02009-09-22 20:41:20152 attributes |= static_cast<uint32>(R_OK);
[email protected]3c5ed2c2009-11-13 01:30:45153 if (!access(file_path.value().c_str(), W_OK))
[email protected]da34ae02009-09-22 20:41:20154 attributes |= static_cast<uint32>(W_OK);
[email protected]b5be3f532009-10-24 01:28:39155 if (!attributes)
[email protected]da34ae02009-09-22 20:41:20156 attributes = -1;
[email protected]da34ae02009-09-22 20:41:20157#endif
158 return attributes;
159}
160
[email protected]a3703dd2010-02-11 17:46:13161// static
[email protected]a3ef4832013-02-02 05:12:33162int64 VfsBackend::GetFileSize(const base::FilePath& file_path) {
[email protected]da34ae02009-09-22 20:41:20163 int64 size = 0;
[email protected]56285702013-12-04 18:22:49164 return (base::GetFileSize(file_path, &size) ? size : 0);
[email protected]da34ae02009-09-22 20:41:20165}
166
[email protected]b5be3f532009-10-24 01:28:39167} // namespace webkit_database