Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1005)

Side by Side Diff: chrome/browser/renderer_host/database_dispatcher_host.cc

Issue 194021: Bug fix: produce unique temp file names when the VFS requests a handle to a n... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Final version. Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util_posix.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/renderer_host/database_dispatcher_host.h" 5 #include "chrome/browser/renderer_host/database_dispatcher_host.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #endif 9 #endif
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 // Every time we get a DB-related message, we AddRef() the resource 58 // Every time we get a DB-related message, we AddRef() the resource
59 // message filterto make sure it doesn't get destroyed before we have 59 // message filterto make sure it doesn't get destroyed before we have
60 // a chance to send the reply back. So we need to Release() is here 60 // a chance to send the reply back. So we need to Release() is here
61 // and allow it to be destroyed if needed. 61 // and allow it to be destroyed if needed.
62 sender->Release(); 62 sender->Release();
63 } 63 }
64 64
65 // Make sure the flags used to open a DB file are consistent. 65 // Make sure the flags used to open a DB file are consistent.
66 static bool OpenFileFlagsAreConsistent(const OpenFileParams& params) { 66 static bool OpenFileFlagsAreConsistent(const OpenFileParams& params) {
67 if (params.file_name == params.db_dir) { 67 // Is this a request for a temp file?
68 return (params.desired_flags == SQLITE_OPEN_READONLY); 68 // We should be able to delete temp files when they're closed
69 // and create them as needed
70 if ((params.file_name == params.db_dir) &&
71 (!(params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) ||
72 !(params.desired_flags & SQLITE_OPEN_CREATE))) {
73 return false;
69 } 74 }
70 75
71 const int file_type = params.desired_flags & 0x00007F00; 76 const int file_type = params.desired_flags & 0x00007F00;
72 const bool is_exclusive = 77 const bool is_exclusive =
73 (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0; 78 (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0;
74 const bool is_delete = 79 const bool is_delete =
75 (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0; 80 (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0;
76 const bool is_create = 81 const bool is_create =
77 (params.desired_flags & SQLITE_OPEN_CREATE) != 0; 82 (params.desired_flags & SQLITE_OPEN_CREATE) != 0;
78 const bool is_read_only = 83 const bool is_read_only =
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) { 164 if (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) {
160 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ | 165 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
161 base::PLATFORM_FILE_EXCLUSIVE_WRITE; 166 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
162 } 167 }
163 168
164 if (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) { 169 if (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
165 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN | 170 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN |
166 base::PLATFORM_FILE_DELETE_ON_CLOSE; 171 base::PLATFORM_FILE_DELETE_ON_CLOSE;
167 } 172 }
168 173
174 // If this is a request for a handle to a temp file, get a unique file name
175 FilePath file_name;
176 if (params.file_name == params.db_dir) {
177 if (!file_util::CreateTemporaryFileInDir(params.db_dir, &file_name)) {
178 file_name = FilePath();
179 }
180 } else {
181 file_name = params.file_name;
182 }
183
169 // Try to open/create the DB file. 184 // Try to open/create the DB file.
170 base::PlatformFile file_handle = 185 base::PlatformFile file_handle =
171 base::CreatePlatformFile(params.file_name.ToWStringHack(), flags, NULL); 186 (file_name.empty() ? base::kInvalidPlatformFileValue :
187 base::CreatePlatformFile(file_name.ToWStringHack(), flags, NULL));
172 if (file_handle != base::kInvalidPlatformFileValue) { 188 if (file_handle != base::kInvalidPlatformFileValue) {
173 #if defined(OS_WIN) 189 #if defined(OS_WIN)
174 // Duplicate the file handle. 190 // Duplicate the file handle.
175 if (!DuplicateHandle(GetCurrentProcess(), file_handle, 191 if (!DuplicateHandle(GetCurrentProcess(), file_handle,
176 params.handle, &target_handle, 0, false, 192 params.handle, &target_handle, 0, false,
177 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 193 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
178 // file_handle is closed whether or not DuplicateHandle succeeds. 194 // file_handle is closed whether or not DuplicateHandle succeeds.
179 target_handle = INVALID_HANDLE_VALUE; 195 target_handle = INVALID_HANDLE_VALUE;
180 } 196 }
181 #elif defined(OS_POSIX) 197 #elif defined(OS_POSIX)
(...skipping 11 matching lines...) Expand all
193 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL); 209 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL);
194 if (target_dir_handle == base::kInvalidPlatformFileValue) { 210 if (target_dir_handle == base::kInvalidPlatformFileValue) {
195 base::ClosePlatformFile(target_handle); 211 base::ClosePlatformFile(target_handle);
196 target_handle = base::kInvalidPlatformFileValue; 212 target_handle = base::kInvalidPlatformFileValue;
197 } 213 }
198 } 214 }
199 #endif 215 #endif
200 } 216 }
201 } 217 }
202 218
203 ViewMsg_DatabaseOpenFileResponse_Params response_params = 219 ViewMsg_DatabaseOpenFileResponse_Params response_params;
204 #if defined(OS_WIN) 220 #if defined(OS_WIN)
205 { target_handle }; 221 response_params.file_handle = target_handle;
206 #elif defined(OS_POSIX) 222 #elif defined(OS_POSIX)
207 { base::FileDescriptor(target_handle, true), 223 response_params.file_handle = base::FileDescriptor(target_handle, true);
208 base::FileDescriptor(target_dir_handle, true) }; 224 response_params.dir_handle = base::FileDescriptor(target_dir_handle, true);
209 #endif 225 #endif
210 226
211 io_thread_message_loop->PostTask(FROM_HERE, 227 io_thread_message_loop->PostTask(FROM_HERE,
212 NewRunnableFunction(SendMessage, sender, 228 NewRunnableFunction(SendMessage, sender,
213 new ViewMsg_DatabaseOpenFileResponse(message_id, response_params))); 229 new ViewMsg_DatabaseOpenFileResponse(message_id, response_params)));
214 } 230 }
215 231
216 // Scheduled by the IO thread on the file thread. 232 // Scheduled by the IO thread on the file thread.
217 // Deletes the given database file, then schedules 233 // Deletes the given database file, then schedules
218 // a task on the IO thread's message loop to send an IPC back to 234 // a task on the IO thread's message loop to send an IPC back to
219 // corresponding renderer process with the error code. 235 // corresponding renderer process with the error code.
220 static void DatabaseDeleteFile( 236 static void DatabaseDeleteFile(
221 MessageLoop* io_thread_message_loop, 237 MessageLoop* io_thread_message_loop,
222 const DeleteFileParams& params, 238 const DeleteFileParams& params,
223 int32 message_id, 239 int32 message_id,
224 int reschedule_count, 240 int reschedule_count,
225 ResourceMessageFilter* sender) { 241 ResourceMessageFilter* sender) {
226 // Return an error if the file could not be deleted 242 // Return an error if the file could not be deleted
227 // after kNumDeleteRetries times. 243 // after kNumDeleteRetries times.
228 if (!reschedule_count) { 244 if (!reschedule_count) {
229 io_thread_message_loop->PostTask(FROM_HERE, 245 io_thread_message_loop->PostTask(FROM_HERE,
230 NewRunnableFunction(SendMessage, sender, 246 NewRunnableFunction(SendMessage, sender,
231 new ViewMsg_DatabaseDeleteFileResponse( 247 new ViewMsg_DatabaseDeleteFileResponse(
232 message_id, SQLITE_IOERR_DELETE))); 248 message_id, SQLITE_IOERR_DELETE)));
233 return; 249 return;
234 } 250 }
235 251
236 // If the file does not exist, we're done. 252 // If the file does not exist, we're done.
237 if (!file_util::PathExists(params.file_name)) { 253 if (!file_util::PathExists(params.file_name)) {
238 io_thread_message_loop->PostTask(FROM_HERE, 254 io_thread_message_loop->PostTask(FROM_HERE,
239 NewRunnableFunction(SendMessage, sender, 255 NewRunnableFunction(SendMessage, sender,
240 new ViewMsg_DatabaseDeleteFileResponse(message_id, SQLITE_OK))); 256 new ViewMsg_DatabaseDeleteFileResponse(message_id, SQLITE_OK)));
241 return; 257 return;
242 } 258 }
243 259
244 260
245 // If the file could not be deleted, try again. 261 // If the file could not be deleted, try again.
246 if (!file_util::Delete(params.file_name, false)) { 262 if (!file_util::Delete(params.file_name, false)) {
247 MessageLoop::current()->PostDelayedTask(FROM_HERE, 263 MessageLoop::current()->PostDelayedTask(FROM_HERE,
248 NewRunnableFunction(DatabaseDeleteFile, io_thread_message_loop, 264 NewRunnableFunction(DatabaseDeleteFile, io_thread_message_loop,
249 params, message_id, reschedule_count - 1, sender), 265 params, message_id, reschedule_count - 1, sender),
250 kDelayDeleteRetryMs); 266 kDelayDeleteRetryMs);
251 return; 267 return;
252 } 268 }
253 269
254 // File existed and it was successfully deleted 270 // File existed and it was successfully deleted
255 int error_code = SQLITE_OK; 271 int error_code = SQLITE_OK;
256 #if defined(OS_POSIX) 272 #if defined(OS_POSIX)
257 // sync the DB directory if needed 273 // sync the DB directory if needed
258 if (params.sync_dir) { 274 if (params.sync_dir) {
259 base::PlatformFile dir_fd = base::CreatePlatformFile( 275 base::PlatformFile dir_fd = base::CreatePlatformFile(
260 params.db_dir.ToWStringHack(), base::PLATFORM_FILE_READ, NULL); 276 params.db_dir.ToWStringHack(), base::PLATFORM_FILE_READ, NULL);
261 if (dir_fd == base::kInvalidPlatformFileValue) { 277 if (dir_fd == base::kInvalidPlatformFileValue) {
262 error_code = SQLITE_CANTOPEN; 278 error_code = SQLITE_CANTOPEN;
263 } else { 279 } else {
264 if (fsync(dir_fd)) { 280 if (fsync(dir_fd)) {
265 error_code = SQLITE_IOERR_DIR_FSYNC; 281 error_code = SQLITE_IOERR_DIR_FSYNC;
266 } 282 }
267 base::ClosePlatformFile(dir_fd); 283 base::ClosePlatformFile(dir_fd);
268 } 284 }
269 } 285 }
270 #endif 286 #endif
271 287
272 io_thread_message_loop->PostTask(FROM_HERE, 288 io_thread_message_loop->PostTask(FROM_HERE,
273 NewRunnableFunction(SendMessage, sender, 289 NewRunnableFunction(SendMessage, sender,
274 new ViewMsg_DatabaseDeleteFileResponse(message_id, error_code))); 290 new ViewMsg_DatabaseDeleteFileResponse(message_id, error_code)));
275 } 291 }
276 292
277 // Scheduled by the IO thread on the file thread. 293 // Scheduled by the IO thread on the file thread.
278 // Gets the attributes of the given database file, then schedules 294 // Gets the attributes of the given database file, then schedules
279 // a task on the IO thread's message loop to send an IPC back to 295 // a task on the IO thread's message loop to send an IPC back to
280 // corresponding renderer process. 296 // corresponding renderer process.
281 static void DatabaseGetFileAttributes( 297 static void DatabaseGetFileAttributes(
282 MessageLoop* io_thread_message_loop, 298 MessageLoop* io_thread_message_loop,
283 const FilePath& file_name, 299 const FilePath& file_name,
284 int32 message_id, 300 int32 message_id,
285 ResourceMessageFilter* sender) { 301 ResourceMessageFilter* sender) {
286 #if defined(OS_WIN) 302 #if defined(OS_WIN)
287 uint32 attributes = GetFileAttributes(file_name.value().c_str()); 303 uint32 attributes = GetFileAttributes(file_name.value().c_str());
288 #elif defined(OS_POSIX) 304 #elif defined(OS_POSIX)
289 uint32 attributes = 0; 305 uint32 attributes = 0;
290 if (!access(file_name.value().c_str(), R_OK)) { 306 if (!access(file_name.value().c_str(), R_OK)) {
291 attributes |= static_cast<uint32>(R_OK); 307 attributes |= static_cast<uint32>(R_OK);
292 } 308 }
293 if (!access(file_name.value().c_str(), W_OK)) { 309 if (!access(file_name.value().c_str(), W_OK)) {
294 attributes |= static_cast<uint32>(W_OK); 310 attributes |= static_cast<uint32>(W_OK);
295 } 311 }
296 if (!attributes) { 312 if (!attributes) {
297 attributes = -1; 313 attributes = -1;
298 } 314 }
299 #endif 315 #endif
300 316
301 io_thread_message_loop->PostTask(FROM_HERE, 317 io_thread_message_loop->PostTask(FROM_HERE,
302 NewRunnableFunction(SendMessage, sender, 318 NewRunnableFunction(SendMessage, sender,
303 new ViewMsg_DatabaseGetFileAttributesResponse(message_id, attributes))); 319 new ViewMsg_DatabaseGetFileAttributesResponse(
320 message_id, attributes)));
304 } 321 }
305 322
306 // Scheduled by the IO thread on the file thread. 323 // Scheduled by the IO thread on the file thread.
307 // Gets the size of the given file, then schedules a task 324 // Gets the size of the given file, then schedules a task
308 // on the IO thread's message loop to send an IPC back to 325 // on the IO thread's message loop to send an IPC back to
309 // the corresponding renderer process. 326 // the corresponding renderer process.
310 static void DatabaseGetFileSize( 327 static void DatabaseGetFileSize(
311 MessageLoop* io_thread_message_loop, 328 MessageLoop* io_thread_message_loop,
312 const FilePath& file_name, 329 const FilePath& file_name,
313 int32 message_id, 330 int32 message_id,
314 ResourceMessageFilter* sender) { 331 ResourceMessageFilter* sender) {
315 int64 size = 0; 332 int64 size = 0;
316 if (!file_util::GetFileSize(file_name, &size)) { 333 if (!file_util::GetFileSize(file_name, &size)) {
317 size = 0; 334 size = 0;
318 } 335 }
319 336
320 io_thread_message_loop->PostTask(FROM_HERE, 337 io_thread_message_loop->PostTask(FROM_HERE,
321 NewRunnableFunction(SendMessage, sender, 338 NewRunnableFunction(SendMessage, sender,
322 new ViewMsg_DatabaseGetFileSizeResponse(message_id, size))); 339 new ViewMsg_DatabaseGetFileSizeResponse(message_id, size)));
323 } 340 }
324 341
325 } // namespace 342 } // namespace
326 343
327 DatabaseDispatcherHost::DatabaseDispatcherHost( 344 DatabaseDispatcherHost::DatabaseDispatcherHost(
328 const FilePath& profile_path, 345 const FilePath& profile_path,
329 ResourceMessageFilter* resource_message_filter) 346 ResourceMessageFilter* resource_message_filter)
330 : profile_path_(profile_path), 347 : profile_path_(profile_path),
331 resource_message_filter_(resource_message_filter), 348 resource_message_filter_(resource_message_filter),
332 file_thread_message_loop_( 349 file_thread_message_loop_(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 398 }
382 return GetDBDir().Append(file_name); 399 return GetDBDir().Append(file_name);
383 } 400 }
384 401
385 void DatabaseDispatcherHost::OnDatabaseOpenFile( 402 void DatabaseDispatcherHost::OnDatabaseOpenFile(
386 const FilePath& file_name, int desired_flags, 403 const FilePath& file_name, int desired_flags,
387 int32 message_id) { 404 int32 message_id) {
388 FilePath db_file_name = GetDBFileFullPath(file_name); 405 FilePath db_file_name = GetDBFileFullPath(file_name);
389 406
390 if (db_file_name.empty()) { 407 if (db_file_name.empty()) {
391 ViewMsg_DatabaseOpenFileResponse_Params response_params = 408 ViewMsg_DatabaseOpenFileResponse_Params response_params;
392 #if defined(OS_WIN) 409 #if defined(OS_WIN)
393 { base::kInvalidPlatformFileValue }; 410 response_params.file_handle = base::kInvalidPlatformFileValue;
394 #elif defined(OS_POSIX) 411 #elif defined(OS_POSIX)
395 { base::FileDescriptor(base::kInvalidPlatformFileValue, true), 412 response_params.file_handle =
396 base::FileDescriptor(base::kInvalidPlatformFileValue, true) }; 413 base::FileDescriptor(base::kInvalidPlatformFileValue, true);
414 response_params.dir_handle =
415 base::FileDescriptor(base::kInvalidPlatformFileValue, true);
397 #endif 416 #endif
398 resource_message_filter_->Send(new ViewMsg_DatabaseOpenFileResponse( 417 resource_message_filter_->Send(new ViewMsg_DatabaseOpenFileResponse(
399 message_id, response_params)); 418 message_id, response_params));
400 return; 419 return;
401 } 420 }
402 421
403 OpenFileParams params = { GetDBDir(), db_file_name, desired_flags, 422 OpenFileParams params = { GetDBDir(), db_file_name, desired_flags,
404 resource_message_filter_->handle() }; 423 resource_message_filter_->handle() };
405 resource_message_filter_->AddRef(); 424 resource_message_filter_->AddRef();
406 file_thread_message_loop_->PostTask(FROM_HERE, 425 file_thread_message_loop_->PostTask(FROM_HERE,
407 NewRunnableFunction(DatabaseOpenFile, MessageLoop::current(), 426 NewRunnableFunction(DatabaseOpenFile, MessageLoop::current(),
408 params, message_id, resource_message_filter_)); 427 params, message_id, resource_message_filter_));
409 } 428 }
410 429
411 void DatabaseDispatcherHost::OnDatabaseDeleteFile( 430 void DatabaseDispatcherHost::OnDatabaseDeleteFile(
412 const FilePath& file_name, const bool& sync_dir, int32 message_id) { 431 const FilePath& file_name, const bool& sync_dir, int32 message_id) {
413 FilePath db_file_name = GetDBFileFullPath(file_name); 432 FilePath db_file_name = GetDBFileFullPath(file_name);
414 if (db_file_name.empty()) { 433 if (db_file_name.empty()) {
415 resource_message_filter_->Send(new ViewMsg_DatabaseDeleteFileResponse( 434 resource_message_filter_->Send(new ViewMsg_DatabaseDeleteFileResponse(
416 message_id, SQLITE_IOERR_DELETE)); 435 message_id, SQLITE_IOERR_DELETE));
417 return; 436 return;
418 } 437 }
419 438
420 DeleteFileParams params = { GetDBDir(), db_file_name, sync_dir }; 439 DeleteFileParams params = { GetDBDir(), db_file_name, sync_dir };
421 resource_message_filter_->AddRef(); 440 resource_message_filter_->AddRef();
422 file_thread_message_loop_->PostTask(FROM_HERE, 441 file_thread_message_loop_->PostTask(FROM_HERE,
423 NewRunnableFunction(DatabaseDeleteFile, MessageLoop::current(), 442 NewRunnableFunction(DatabaseDeleteFile, MessageLoop::current(),
424 params, message_id, kNumDeleteRetries, resource_message_filter_)); 443 params, message_id, kNumDeleteRetries, resource_message_filter_));
425 } 444 }
426 445
427 void DatabaseDispatcherHost::OnDatabaseGetFileAttributes( 446 void DatabaseDispatcherHost::OnDatabaseGetFileAttributes(
428 const FilePath& file_name, int32 message_id) { 447 const FilePath& file_name, int32 message_id) {
429 FilePath db_file_name = GetDBFileFullPath(file_name); 448 FilePath db_file_name = GetDBFileFullPath(file_name);
430 if (db_file_name.empty()) { 449 if (db_file_name.empty()) {
431 resource_message_filter_->Send( 450 resource_message_filter_->Send(
432 new ViewMsg_DatabaseGetFileAttributesResponse( 451 new ViewMsg_DatabaseGetFileAttributesResponse(
433 message_id, -1)); 452 message_id, -1));
434 return; 453 return;
435 } 454 }
436 455
437 resource_message_filter_->AddRef(); 456 resource_message_filter_->AddRef();
438 file_thread_message_loop_->PostTask(FROM_HERE, 457 file_thread_message_loop_->PostTask(FROM_HERE,
439 NewRunnableFunction(DatabaseGetFileAttributes, MessageLoop::current(), 458 NewRunnableFunction(DatabaseGetFileAttributes, MessageLoop::current(),
440 db_file_name, message_id, resource_message_filter_)); 459 db_file_name, message_id, resource_message_filter_));
441 } 460 }
442 461
443 void DatabaseDispatcherHost::OnDatabaseGetFileSize( 462 void DatabaseDispatcherHost::OnDatabaseGetFileSize(
444 const FilePath& file_name, int32 message_id) { 463 const FilePath& file_name, int32 message_id) {
445 FilePath db_file_name = GetDBFileFullPath(file_name); 464 FilePath db_file_name = GetDBFileFullPath(file_name);
446 if (db_file_name.empty()) { 465 if (db_file_name.empty()) {
447 resource_message_filter_->Send(new ViewMsg_DatabaseGetFileSizeResponse( 466 resource_message_filter_->Send(new ViewMsg_DatabaseGetFileSizeResponse(
448 message_id, 0)); 467 message_id, 0));
449 return; 468 return;
450 } 469 }
451 470
452 resource_message_filter_->AddRef(); 471 resource_message_filter_->AddRef();
453 file_thread_message_loop_->PostTask(FROM_HERE, 472 file_thread_message_loop_->PostTask(FROM_HERE,
454 NewRunnableFunction(DatabaseGetFileSize, MessageLoop::current(), 473 NewRunnableFunction(DatabaseGetFileSize, MessageLoop::current(),
455 db_file_name, message_id, resource_message_filter_)); 474 db_file_name, message_id, resource_message_filter_));
456 } 475 }
OLDNEW
« no previous file with comments | « base/file_util_posix.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698