blob: 7ed0874b5bd8f5faa1e2012f9f13dffbe589f378 [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
[email protected]cd501a72014-08-22 19:58:3112namespace storage {
[email protected]da34ae02009-09-22 20:41:2013
[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]382aa7e2014-03-28 01:13:3758base::File VfsBackend::OpenFile(const base::FilePath& file_path,
59 int desired_flags) {
[email protected]3c5ed2c2009-11-13 01:30:4560 DCHECK(!file_path.empty());
61
[email protected]da34ae02009-09-22 20:41:2062 // Verify the flags for consistency and create the database
63 // directory if it doesn't exist.
[email protected]3c5ed2c2009-11-13 01:30:4564 if (!OpenFileFlagsAreConsistent(desired_flags) ||
[email protected]382aa7e2014-03-28 01:13:3765 !base::CreateDirectory(file_path.DirName())) {
66 return base::File();
67 }
[email protected]da34ae02009-09-22 20:41:2068
[email protected]c93efc7c52009-10-29 19:58:3069 int flags = 0;
[email protected]382aa7e2014-03-28 01:13:3770 flags |= base::File::FLAG_READ;
[email protected]c93efc7c52009-10-29 19:58:3071 if (desired_flags & SQLITE_OPEN_READWRITE)
[email protected]382aa7e2014-03-28 01:13:3772 flags |= base::File::FLAG_WRITE;
[email protected]da34ae02009-09-22 20:41:2073
[email protected]382aa7e2014-03-28 01:13:3774 if (!(desired_flags & SQLITE_OPEN_MAIN_DB))
75 flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;
[email protected]da34ae02009-09-22 20:41:2076
[email protected]c93efc7c52009-10-29 19:58:3077 flags |= ((desired_flags & SQLITE_OPEN_CREATE) ?
[email protected]382aa7e2014-03-28 01:13:3778 base::File::FLAG_OPEN_ALWAYS : base::File::FLAG_OPEN);
[email protected]da34ae02009-09-22 20:41:2079
[email protected]382aa7e2014-03-28 01:13:3780 if (desired_flags & SQLITE_OPEN_EXCLUSIVE)
81 flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;
[email protected]da34ae02009-09-22 20:41:2082
[email protected]c93efc7c52009-10-29 19:58:3083 if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
[email protected]382aa7e2014-03-28 01:13:3784 flags |= base::File::FLAG_TEMPORARY | base::File::FLAG_HIDDEN |
85 base::File::FLAG_DELETE_ON_CLOSE;
[email protected]c93efc7c52009-10-29 19:58:3086 }
[email protected]da34ae02009-09-22 20:41:2087
[email protected]800ad562011-07-08 08:00:5088 // This flag will allow us to delete the file later on from the browser
89 // process.
[email protected]382aa7e2014-03-28 01:13:3790 flags |= base::File::FLAG_SHARE_DELETE;
[email protected]800ad562011-07-08 08:00:5091
[email protected]c93efc7c52009-10-29 19:58:3092 // Try to open/create the DB file.
[email protected]382aa7e2014-03-28 01:13:3793 return base::File(file_path, flags);
[email protected]da34ae02009-09-22 20:41:2094}
95
[email protected]a3703dd2010-02-11 17:46:1396// static
[email protected]382aa7e2014-03-28 01:13:3797base::File VfsBackend::OpenTempFileInDirectory(const base::FilePath& dir_path,
98 int desired_flags) {
[email protected]3c5ed2c2009-11-13 01:30:4599 // We should be able to delete temp files when they're closed
100 // and create them as needed
101 if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) ||
102 !(desired_flags & SQLITE_OPEN_CREATE)) {
[email protected]382aa7e2014-03-28 01:13:37103 return base::File();
[email protected]3c5ed2c2009-11-13 01:30:45104 }
105
106 // Get a unique temp file name in the database directory.
[email protected]a3ef4832013-02-02 05:12:33107 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:52108 if (!base::CreateTemporaryFileInDir(dir_path, &temp_file_path))
[email protected]382aa7e2014-03-28 01:13:37109 return base::File();
[email protected]3c5ed2c2009-11-13 01:30:45110
[email protected]382aa7e2014-03-28 01:13:37111 return OpenFile(temp_file_path, desired_flags);
[email protected]3c5ed2c2009-11-13 01:30:45112}
113
[email protected]a3703dd2010-02-11 17:46:13114// static
[email protected]a3ef4832013-02-02 05:12:33115int VfsBackend::DeleteFile(const base::FilePath& file_path, bool sync_dir) {
[email protected]7567484142013-07-11 17:36:07116 if (!base::PathExists(file_path))
[email protected]da34ae02009-09-22 20:41:20117 return SQLITE_OK;
[email protected]dd3aa792013-07-16 19:10:23118 if (!base::DeleteFile(file_path, false))
[email protected]da34ae02009-09-22 20:41:20119 return SQLITE_IOERR_DELETE;
[email protected]da34ae02009-09-22 20:41:20120
121 int error_code = SQLITE_OK;
122#if defined(OS_POSIX)
123 if (sync_dir) {
[email protected]382aa7e2014-03-28 01:13:37124 base::File dir(file_path.DirName(), base::File::FLAG_READ);
125 if (dir.IsValid()) {
126 if (!dir.Flush())
[email protected]da34ae02009-09-22 20:41:20127 error_code = SQLITE_IOERR_DIR_FSYNC;
[email protected]382aa7e2014-03-28 01:13:37128 } else {
129 error_code = SQLITE_CANTOPEN;
[email protected]da34ae02009-09-22 20:41:20130 }
131 }
132#endif
133 return error_code;
134}
135
[email protected]a3703dd2010-02-11 17:46:13136// static
[email protected]a3ef4832013-02-02 05:12:33137uint32 VfsBackend::GetFileAttributes(const base::FilePath& file_path) {
[email protected]da34ae02009-09-22 20:41:20138#if defined(OS_WIN)
[email protected]3c5ed2c2009-11-13 01:30:45139 uint32 attributes = ::GetFileAttributes(file_path.value().c_str());
[email protected]da34ae02009-09-22 20:41:20140#elif defined(OS_POSIX)
141 uint32 attributes = 0;
[email protected]3c5ed2c2009-11-13 01:30:45142 if (!access(file_path.value().c_str(), R_OK))
[email protected]da34ae02009-09-22 20:41:20143 attributes |= static_cast<uint32>(R_OK);
[email protected]3c5ed2c2009-11-13 01:30:45144 if (!access(file_path.value().c_str(), W_OK))
[email protected]da34ae02009-09-22 20:41:20145 attributes |= static_cast<uint32>(W_OK);
[email protected]b5be3f532009-10-24 01:28:39146 if (!attributes)
[email protected]da34ae02009-09-22 20:41:20147 attributes = -1;
[email protected]da34ae02009-09-22 20:41:20148#endif
149 return attributes;
150}
151
[email protected]a3703dd2010-02-11 17:46:13152// static
[email protected]a3ef4832013-02-02 05:12:33153int64 VfsBackend::GetFileSize(const base::FilePath& file_path) {
[email protected]da34ae02009-09-22 20:41:20154 int64 size = 0;
[email protected]56285702013-12-04 18:22:49155 return (base::GetFileSize(file_path, &size) ? size : 0);
[email protected]da34ae02009-09-22 20:41:20156}
157
[email protected]cd501a72014-08-22 19:58:31158} // namespace storage