| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/database/vfs_backend.h" | 5 #include "webkit/database/vfs_backend.h" |
| 6 | 6 |
| 7 #if defined(USE_SYSTEM_SQLITE) | 7 #if defined(USE_SYSTEM_SQLITE) |
| 8 #include <sqlite3.h> | 8 #include <sqlite3.h> |
| 9 #else | 9 #else |
| 10 #include "third_party/sqlite/preprocessed/sqlite3.h" | 10 #include "third_party/sqlite/preprocessed/sqlite3.h" |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include "base/file_path.h" | 13 #include "base/file_path.h" |
| 14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 | 16 |
| 17 namespace webkit_database { | 17 namespace webkit_database { |
| 18 | 18 |
| 19 static const int kFileTypeMask = 0x00007F00; | 19 static const int kFileTypeMask = 0x00007F00; |
| 20 | 20 |
| 21 // static | 21 // static |
| 22 void VfsBackend::GetFileHandleForProcess(base::ProcessHandle process_handle, |
| 23 const base::PlatformFile& file_handle, |
| 24 base::PlatformFile* target_handle, |
| 25 bool close_source_handle) { |
| 26 if (file_handle == base::kInvalidPlatformFileValue) { |
| 27 *target_handle = base::kInvalidPlatformFileValue; |
| 28 return; |
| 29 } |
| 30 |
| 31 #if defined(OS_WIN) |
| 32 // Duplicate the file handle. |
| 33 if (!DuplicateHandle(GetCurrentProcess(), file_handle, |
| 34 process_handle, target_handle, 0, false, |
| 35 DUPLICATE_SAME_ACCESS | |
| 36 (close_source_handle ? DUPLICATE_CLOSE_SOURCE : 0))) { |
| 37 // file_handle is closed whether or not DuplicateHandle succeeds. |
| 38 *target_handle = INVALID_HANDLE_VALUE; |
| 39 } |
| 40 #elif defined(OS_POSIX) |
| 41 *target_handle = file_handle; |
| 42 #endif |
| 43 } |
| 44 |
| 45 // static |
| 22 bool VfsBackend::FileTypeIsMainDB(int desired_flags) { | 46 bool VfsBackend::FileTypeIsMainDB(int desired_flags) { |
| 23 return (desired_flags & kFileTypeMask) == SQLITE_OPEN_MAIN_DB; | 47 return (desired_flags & kFileTypeMask) == SQLITE_OPEN_MAIN_DB; |
| 24 } | 48 } |
| 25 | 49 |
| 26 // static | 50 // static |
| 51 bool VfsBackend::FileTypeIsJournal(int desired_flags) { |
| 52 int file_type = desired_flags & kFileTypeMask; |
| 53 return ((file_type == SQLITE_OPEN_MAIN_JOURNAL) || |
| 54 (file_type == SQLITE_OPEN_TEMP_JOURNAL) || |
| 55 (file_type == SQLITE_OPEN_SUBJOURNAL) || |
| 56 (file_type == SQLITE_OPEN_MASTER_JOURNAL)); |
| 57 } |
| 58 |
| 59 // static |
| 27 bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) { | 60 bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) { |
| 28 return (desired_flags & SQLITE_OPEN_READWRITE) != 0; | 61 return (desired_flags & SQLITE_OPEN_READWRITE) != 0; |
| 29 } | 62 } |
| 30 | 63 |
| 31 // static | 64 // static |
| 32 bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) { | 65 bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) { |
| 33 const int file_type = desired_flags & kFileTypeMask; | 66 const int file_type = desired_flags & kFileTypeMask; |
| 34 const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0; | 67 const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0; |
| 35 const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0; | 68 const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0; |
| 36 const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0; | 69 const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0; |
| 37 const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0; | 70 const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0; |
| 38 const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0; | 71 const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0; |
| 39 | 72 |
| 40 // All files should be opened either read-write or read-only, but not both. | 73 // All files should be opened either read-write or read-only, but not both. |
| 41 if (is_read_only == is_read_write) | 74 if (is_read_only == is_read_write) |
| 42 return false; | 75 return false; |
| 43 | 76 |
| 44 // If a new file is created, it must also be writable. | 77 // If a new file is created, it must also be writable. |
| 45 if (is_create && !is_read_write) | 78 if (is_create && !is_read_write) |
| 46 return false; | 79 return false; |
| 47 | 80 |
| 48 // If we're accessing an existing file, we cannot give exclusive access, and | 81 // If we're accessing an existing file, we cannot give exclusive access, and |
| 49 // we can't delete it. | 82 // we can't delete it. |
| 83 // Normally, we'd also check that 'is_delete' is false for a main DB, main |
| 84 // journal or master journal file; however, when in incognito mode, we use |
| 85 // the SQLITE_OPEN_DELETEONCLOSE flag when opening those files too and keep |
| 86 // an open handle to them for as long as the incognito profile is around. |
| 50 if ((is_exclusive || is_delete) && !is_create) | 87 if ((is_exclusive || is_delete) && !is_create) |
| 51 return false; | 88 return false; |
| 52 | 89 |
| 53 // The main DB, main journal and master journal cannot be auto-deleted. | |
| 54 if (is_delete && ((file_type == SQLITE_OPEN_MAIN_DB) || | |
| 55 (file_type == SQLITE_OPEN_MAIN_JOURNAL) || | |
| 56 (file_type == SQLITE_OPEN_MASTER_JOURNAL))) { | |
| 57 return false; | |
| 58 } | |
| 59 | |
| 60 // Make sure we're opening the DB directory or that a file type is set. | 90 // Make sure we're opening the DB directory or that a file type is set. |
| 61 return (file_type == SQLITE_OPEN_MAIN_DB) || | 91 return (file_type == SQLITE_OPEN_MAIN_DB) || |
| 62 (file_type == SQLITE_OPEN_TEMP_DB) || | 92 (file_type == SQLITE_OPEN_TEMP_DB) || |
| 63 (file_type == SQLITE_OPEN_MAIN_JOURNAL) || | 93 (file_type == SQLITE_OPEN_MAIN_JOURNAL) || |
| 64 (file_type == SQLITE_OPEN_TEMP_JOURNAL) || | 94 (file_type == SQLITE_OPEN_TEMP_JOURNAL) || |
| 65 (file_type == SQLITE_OPEN_SUBJOURNAL) || | 95 (file_type == SQLITE_OPEN_SUBJOURNAL) || |
| 66 (file_type == SQLITE_OPEN_MASTER_JOURNAL) || | 96 (file_type == SQLITE_OPEN_MASTER_JOURNAL) || |
| 67 (file_type == SQLITE_OPEN_TRANSIENT_DB); | 97 (file_type == SQLITE_OPEN_TRANSIENT_DB); |
| 68 } | 98 } |
| 69 | 99 |
| 70 // static | 100 // static |
| 71 void VfsBackend::OpenFile(const FilePath& file_path, | 101 void VfsBackend::OpenFile(const FilePath& file_path, |
| 72 int desired_flags, | 102 int desired_flags, |
| 73 base::ProcessHandle handle, | 103 base::PlatformFile* file_handle) { |
| 74 base::PlatformFile* target_handle) { | |
| 75 DCHECK(!file_path.empty()); | 104 DCHECK(!file_path.empty()); |
| 76 | 105 |
| 77 // Verify the flags for consistency and create the database | 106 // Verify the flags for consistency and create the database |
| 78 // directory if it doesn't exist. | 107 // directory if it doesn't exist. |
| 79 if (!OpenFileFlagsAreConsistent(desired_flags) || | 108 if (!OpenFileFlagsAreConsistent(desired_flags) || |
| 80 !file_util::CreateDirectory(file_path.DirName())) | 109 !file_util::CreateDirectory(file_path.DirName())) |
| 81 return; | 110 return; |
| 82 | 111 |
| 83 int flags = 0; | 112 int flags = 0; |
| 84 flags |= base::PLATFORM_FILE_READ; | 113 flags |= base::PLATFORM_FILE_READ; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 97 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ | | 126 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ | |
| 98 base::PLATFORM_FILE_EXCLUSIVE_WRITE; | 127 base::PLATFORM_FILE_EXCLUSIVE_WRITE; |
| 99 } | 128 } |
| 100 | 129 |
| 101 if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) { | 130 if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) { |
| 102 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN | | 131 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN | |
| 103 base::PLATFORM_FILE_DELETE_ON_CLOSE; | 132 base::PLATFORM_FILE_DELETE_ON_CLOSE; |
| 104 } | 133 } |
| 105 | 134 |
| 106 // Try to open/create the DB file. | 135 // Try to open/create the DB file. |
| 107 base::PlatformFile file_handle = | 136 *file_handle = |
| 108 base::CreatePlatformFile(file_path.ToWStringHack(), flags, NULL); | 137 base::CreatePlatformFile(file_path.ToWStringHack(), flags, NULL); |
| 109 if (file_handle != base::kInvalidPlatformFileValue) { | |
| 110 #if defined(OS_WIN) | |
| 111 // Duplicate the file handle. | |
| 112 if (!DuplicateHandle(GetCurrentProcess(), file_handle, | |
| 113 handle, target_handle, 0, false, | |
| 114 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | |
| 115 // file_handle is closed whether or not DuplicateHandle succeeds. | |
| 116 *target_handle = INVALID_HANDLE_VALUE; | |
| 117 } | |
| 118 #elif defined(OS_POSIX) | |
| 119 *target_handle = file_handle; | |
| 120 #endif | |
| 121 } | |
| 122 } | 138 } |
| 123 | 139 |
| 124 // static | 140 // static |
| 125 void VfsBackend::OpenTempFileInDirectory( | 141 void VfsBackend::OpenTempFileInDirectory( |
| 126 const FilePath& dir_path, | 142 const FilePath& dir_path, |
| 127 int desired_flags, | 143 int desired_flags, |
| 128 base::ProcessHandle handle, | 144 base::PlatformFile* file_handle) { |
| 129 base::PlatformFile* target_handle) { | |
| 130 // We should be able to delete temp files when they're closed | 145 // We should be able to delete temp files when they're closed |
| 131 // and create them as needed | 146 // and create them as needed |
| 132 if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) || | 147 if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) || |
| 133 !(desired_flags & SQLITE_OPEN_CREATE)) { | 148 !(desired_flags & SQLITE_OPEN_CREATE)) { |
| 134 return; | 149 return; |
| 135 } | 150 } |
| 136 | 151 |
| 137 // Get a unique temp file name in the database directory. | 152 // Get a unique temp file name in the database directory. |
| 138 FilePath temp_file_path; | 153 FilePath temp_file_path; |
| 139 if (!file_util::CreateTemporaryFileInDir(dir_path, &temp_file_path)) | 154 if (!file_util::CreateTemporaryFileInDir(dir_path, &temp_file_path)) |
| 140 return; | 155 return; |
| 141 | 156 |
| 142 OpenFile(temp_file_path, desired_flags, handle, target_handle); | 157 OpenFile(temp_file_path, desired_flags, file_handle); |
| 143 } | 158 } |
| 144 | 159 |
| 145 // static | 160 // static |
| 146 int VfsBackend::DeleteFile(const FilePath& file_path, bool sync_dir) { | 161 int VfsBackend::DeleteFile(const FilePath& file_path, bool sync_dir) { |
| 147 if (!file_util::PathExists(file_path)) | 162 if (!file_util::PathExists(file_path)) |
| 148 return SQLITE_OK; | 163 return SQLITE_OK; |
| 149 if (!file_util::Delete(file_path, false)) | 164 if (!file_util::Delete(file_path, false)) |
| 150 return SQLITE_IOERR_DELETE; | 165 return SQLITE_IOERR_DELETE; |
| 151 | 166 |
| 152 int error_code = SQLITE_OK; | 167 int error_code = SQLITE_OK; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 182 return attributes; | 197 return attributes; |
| 183 } | 198 } |
| 184 | 199 |
| 185 // static | 200 // static |
| 186 int64 VfsBackend::GetFileSize(const FilePath& file_path) { | 201 int64 VfsBackend::GetFileSize(const FilePath& file_path) { |
| 187 int64 size = 0; | 202 int64 size = 0; |
| 188 return (file_util::GetFileSize(file_path, &size) ? size : 0); | 203 return (file_util::GetFileSize(file_path, &size) ? size : 0); |
| 189 } | 204 } |
| 190 | 205 |
| 191 } // namespace webkit_database | 206 } // namespace webkit_database |
| OLD | NEW |