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

Side by Side Diff: base/file_util_posix.cc

Issue 3872002: Thread IO safety: file_util annotated, IO thread blocked from doing IO (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 10 years, 2 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 | « no previous file | base/shared_memory_posix.cc » ('j') | 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) 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 "base/file_util.h" 5 #include "base/file_util.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <fnmatch.h> 10 #include <fnmatch.h>
(...skipping 21 matching lines...) Expand all
32 32
33 #include "base/basictypes.h" 33 #include "base/basictypes.h"
34 #include "base/eintr_wrapper.h" 34 #include "base/eintr_wrapper.h"
35 #include "base/file_path.h" 35 #include "base/file_path.h"
36 #include "base/lock.h" 36 #include "base/lock.h"
37 #include "base/logging.h" 37 #include "base/logging.h"
38 #include "base/scoped_ptr.h" 38 #include "base/scoped_ptr.h"
39 #include "base/singleton.h" 39 #include "base/singleton.h"
40 #include "base/string_util.h" 40 #include "base/string_util.h"
41 #include "base/sys_string_conversions.h" 41 #include "base/sys_string_conversions.h"
42 #include "base/thread_restrictions.h"
42 #include "base/time.h" 43 #include "base/time.h"
43 #include "base/utf_string_conversions.h" 44 #include "base/utf_string_conversions.h"
44 45
45 namespace file_util { 46 namespace file_util {
46 47
47 namespace { 48 namespace {
48 49
49 // Helper for NormalizeFilePath(), defined below. 50 // Helper for NormalizeFilePath(), defined below.
50 bool RealPath(const FilePath& path, FilePath* real_path) { 51 bool RealPath(const FilePath& path, FilePath* real_path) {
52 base::ThreadRestrictions::AssertIOAllowed(); // For realpath().
51 FilePath::CharType buf[PATH_MAX]; 53 FilePath::CharType buf[PATH_MAX];
52 if (!realpath(path.value().c_str(), buf)) 54 if (!realpath(path.value().c_str(), buf))
53 return false; 55 return false;
54 56
55 *real_path = FilePath(buf); 57 *real_path = FilePath(buf);
56 return true; 58 return true;
57 } 59 }
58 60
59 } // namespace 61 } // namespace
60 62
61 #if defined(OS_OPENBSD) || defined(OS_FREEBSD) || \ 63 #if defined(OS_OPENBSD) || defined(OS_FREEBSD) || \
62 (defined(OS_MACOSX) && \ 64 (defined(OS_MACOSX) && \
63 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) 65 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
64 typedef struct stat stat_wrapper_t; 66 typedef struct stat stat_wrapper_t;
65 static int CallStat(const char *path, stat_wrapper_t *sb) { 67 static int CallStat(const char *path, stat_wrapper_t *sb) {
68 base::ThreadRestrictions::AssertIOAllowed();
66 return stat(path, sb); 69 return stat(path, sb);
67 } 70 }
68 #else 71 #else
69 typedef struct stat64 stat_wrapper_t; 72 typedef struct stat64 stat_wrapper_t;
70 static int CallStat(const char *path, stat_wrapper_t *sb) { 73 static int CallStat(const char *path, stat_wrapper_t *sb) {
74 base::ThreadRestrictions::AssertIOAllowed();
71 return stat64(path, sb); 75 return stat64(path, sb);
72 } 76 }
73 #endif 77 #endif
74 78
75 79
76 #if defined(GOOGLE_CHROME_BUILD) 80 #if defined(GOOGLE_CHROME_BUILD)
77 static const char* kTempFileName = ".com.google.chrome.XXXXXX"; 81 static const char* kTempFileName = ".com.google.chrome.XXXXXX";
78 #else 82 #else
79 static const char* kTempFileName = ".org.chromium.XXXXXX"; 83 static const char* kTempFileName = ".org.chromium.XXXXXX";
80 #endif 84 #endif
81 85
82 bool AbsolutePath(FilePath* path) { 86 bool AbsolutePath(FilePath* path) {
87 base::ThreadRestrictions::AssertIOAllowed(); // For realpath().
83 char full_path[PATH_MAX]; 88 char full_path[PATH_MAX];
84 if (realpath(path->value().c_str(), full_path) == NULL) 89 if (realpath(path->value().c_str(), full_path) == NULL)
85 return false; 90 return false;
86 *path = FilePath(full_path); 91 *path = FilePath(full_path);
87 return true; 92 return true;
88 } 93 }
89 94
90 int CountFilesCreatedAfter(const FilePath& path, 95 int CountFilesCreatedAfter(const FilePath& path,
91 const base::Time& comparison_time) { 96 const base::Time& comparison_time) {
97 base::ThreadRestrictions::AssertIOAllowed();
92 int file_count = 0; 98 int file_count = 0;
93 99
94 DIR* dir = opendir(path.value().c_str()); 100 DIR* dir = opendir(path.value().c_str());
95 if (dir) { 101 if (dir) {
96 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ 102 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \
97 !defined(OS_OPENBSD) && !defined(OS_SOLARIS) 103 !defined(OS_OPENBSD) && !defined(OS_SOLARIS)
98 #error Port warning: depending on the definition of struct dirent, \ 104 #error Port warning: depending on the definition of struct dirent, \
99 additional space for pathname may be needed 105 additional space for pathname may be needed
100 #endif 106 #endif
101 struct dirent ent_buf; 107 struct dirent ent_buf;
(...skipping 30 matching lines...) Expand all
132 closedir(dir); 138 closedir(dir);
133 } 139 }
134 return file_count; 140 return file_count;
135 } 141 }
136 142
137 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" 143 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*"
138 // which works both with and without the recursive flag. I'm not sure we need 144 // which works both with and without the recursive flag. I'm not sure we need
139 // that functionality. If not, remove from file_util_win.cc, otherwise add it 145 // that functionality. If not, remove from file_util_win.cc, otherwise add it
140 // here. 146 // here.
141 bool Delete(const FilePath& path, bool recursive) { 147 bool Delete(const FilePath& path, bool recursive) {
148 base::ThreadRestrictions::AssertIOAllowed();
142 const char* path_str = path.value().c_str(); 149 const char* path_str = path.value().c_str();
143 stat_wrapper_t file_info; 150 stat_wrapper_t file_info;
144 int test = CallStat(path_str, &file_info); 151 int test = CallStat(path_str, &file_info);
145 if (test != 0) { 152 if (test != 0) {
146 // The Windows version defines this condition as success. 153 // The Windows version defines this condition as success.
147 bool ret = (errno == ENOENT || errno == ENOTDIR); 154 bool ret = (errno == ENOENT || errno == ENOTDIR);
148 return ret; 155 return ret;
149 } 156 }
150 if (!S_ISDIR(file_info.st_mode)) 157 if (!S_ISDIR(file_info.st_mode))
151 return (unlink(path_str) == 0); 158 return (unlink(path_str) == 0);
(...skipping 19 matching lines...) Expand all
171 178
172 while (success && !directories.empty()) { 179 while (success && !directories.empty()) {
173 FilePath dir = FilePath(directories.top()); 180 FilePath dir = FilePath(directories.top());
174 directories.pop(); 181 directories.pop();
175 success = (rmdir(dir.value().c_str()) == 0); 182 success = (rmdir(dir.value().c_str()) == 0);
176 } 183 }
177 return success; 184 return success;
178 } 185 }
179 186
180 bool Move(const FilePath& from_path, const FilePath& to_path) { 187 bool Move(const FilePath& from_path, const FilePath& to_path) {
188 base::ThreadRestrictions::AssertIOAllowed();
181 // Windows compatibility: if to_path exists, from_path and to_path 189 // Windows compatibility: if to_path exists, from_path and to_path
182 // must be the same type, either both files, or both directories. 190 // must be the same type, either both files, or both directories.
183 stat_wrapper_t to_file_info; 191 stat_wrapper_t to_file_info;
184 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { 192 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) {
185 stat_wrapper_t from_file_info; 193 stat_wrapper_t from_file_info;
186 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { 194 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) {
187 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) 195 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode))
188 return false; 196 return false;
189 } else { 197 } else {
190 return false; 198 return false;
191 } 199 }
192 } 200 }
193 201
194 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) 202 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
195 return true; 203 return true;
196 204
197 if (!CopyDirectory(from_path, to_path, true)) 205 if (!CopyDirectory(from_path, to_path, true))
198 return false; 206 return false;
199 207
200 Delete(from_path, true); 208 Delete(from_path, true);
201 return true; 209 return true;
202 } 210 }
203 211
204 bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) { 212 bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) {
213 base::ThreadRestrictions::AssertIOAllowed();
205 return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0); 214 return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0);
206 } 215 }
207 216
208 bool CopyDirectory(const FilePath& from_path, 217 bool CopyDirectory(const FilePath& from_path,
209 const FilePath& to_path, 218 const FilePath& to_path,
210 bool recursive) { 219 bool recursive) {
220 base::ThreadRestrictions::AssertIOAllowed();
211 // Some old callers of CopyDirectory want it to support wildcards. 221 // Some old callers of CopyDirectory want it to support wildcards.
212 // After some discussion, we decided to fix those callers. 222 // After some discussion, we decided to fix those callers.
213 // Break loudly here if anyone tries to do this. 223 // Break loudly here if anyone tries to do this.
214 // TODO(evanm): remove this once we're sure it's ok. 224 // TODO(evanm): remove this once we're sure it's ok.
215 DCHECK(to_path.value().find('*') == std::string::npos); 225 DCHECK(to_path.value().find('*') == std::string::npos);
216 DCHECK(from_path.value().find('*') == std::string::npos); 226 DCHECK(from_path.value().find('*') == std::string::npos);
217 227
218 char top_dir[PATH_MAX]; 228 char top_dir[PATH_MAX];
219 if (base::strlcpy(top_dir, from_path.value().c_str(), 229 if (base::strlcpy(top_dir, from_path.value().c_str(),
220 arraysize(top_dir)) >= arraysize(top_dir)) { 230 arraysize(top_dir)) >= arraysize(top_dir)) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 310 }
301 311
302 current = traversal.Next(); 312 current = traversal.Next();
303 traversal.GetFindInfo(&info); 313 traversal.GetFindInfo(&info);
304 } 314 }
305 315
306 return success; 316 return success;
307 } 317 }
308 318
309 bool PathExists(const FilePath& path) { 319 bool PathExists(const FilePath& path) {
320 base::ThreadRestrictions::AssertIOAllowed();
310 return access(path.value().c_str(), F_OK) == 0; 321 return access(path.value().c_str(), F_OK) == 0;
311 } 322 }
312 323
313 bool PathIsWritable(const FilePath& path) { 324 bool PathIsWritable(const FilePath& path) {
325 base::ThreadRestrictions::AssertIOAllowed();
314 return access(path.value().c_str(), W_OK) == 0; 326 return access(path.value().c_str(), W_OK) == 0;
315 } 327 }
316 328
317 bool DirectoryExists(const FilePath& path) { 329 bool DirectoryExists(const FilePath& path) {
330 base::ThreadRestrictions::AssertIOAllowed();
318 stat_wrapper_t file_info; 331 stat_wrapper_t file_info;
319 if (CallStat(path.value().c_str(), &file_info) == 0) 332 if (CallStat(path.value().c_str(), &file_info) == 0)
320 return S_ISDIR(file_info.st_mode); 333 return S_ISDIR(file_info.st_mode);
321 return false; 334 return false;
322 } 335 }
323 336
324 // TODO(erikkay): implement 337 // TODO(erikkay): implement
325 #if 0 338 #if 0
326 bool GetFileCreationLocalTimeFromHandle(int fd, 339 bool GetFileCreationLocalTimeFromHandle(int fd,
327 LPSYSTEMTIME creation_time) { 340 LPSYSTEMTIME creation_time) {
(...skipping 30 matching lines...) Expand all
358 break; 371 break;
359 total_read += bytes_read; 372 total_read += bytes_read;
360 } 373 }
361 return total_read == bytes; 374 return total_read == bytes;
362 } 375 }
363 376
364 // Creates and opens a temporary file in |directory|, returning the 377 // Creates and opens a temporary file in |directory|, returning the
365 // file descriptor. |path| is set to the temporary file path. 378 // file descriptor. |path| is set to the temporary file path.
366 // This function does NOT unlink() the file. 379 // This function does NOT unlink() the file.
367 int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { 380 int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) {
381 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp().
368 *path = directory.Append(kTempFileName); 382 *path = directory.Append(kTempFileName);
369 const std::string& tmpdir_string = path->value(); 383 const std::string& tmpdir_string = path->value();
370 // this should be OK since mkstemp just replaces characters in place 384 // this should be OK since mkstemp just replaces characters in place
371 char* buffer = const_cast<char*>(tmpdir_string.c_str()); 385 char* buffer = const_cast<char*>(tmpdir_string.c_str());
372 386
373 return mkstemp(buffer); 387 return mkstemp(buffer);
374 } 388 }
375 389
376 bool CreateTemporaryFile(FilePath* path) { 390 bool CreateTemporaryFile(FilePath* path) {
391 base::ThreadRestrictions::AssertIOAllowed(); // For call to close().
377 FilePath directory; 392 FilePath directory;
378 if (!GetTempDir(&directory)) 393 if (!GetTempDir(&directory))
379 return false; 394 return false;
380 int fd = CreateAndOpenFdForTemporaryFile(directory, path); 395 int fd = CreateAndOpenFdForTemporaryFile(directory, path);
381 if (fd < 0) 396 if (fd < 0)
382 return false; 397 return false;
383 close(fd); 398 close(fd);
384 return true; 399 return true;
385 } 400 }
386 401
387 FILE* CreateAndOpenTemporaryShmemFile(FilePath* path) { 402 FILE* CreateAndOpenTemporaryShmemFile(FilePath* path) {
388 FilePath directory; 403 FilePath directory;
389 if (!GetShmemTempDir(&directory)) 404 if (!GetShmemTempDir(&directory))
390 return NULL; 405 return NULL;
391 406
392 return CreateAndOpenTemporaryFileInDir(directory, path); 407 return CreateAndOpenTemporaryFileInDir(directory, path);
393 } 408 }
394 409
395 FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { 410 FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) {
396 int fd = CreateAndOpenFdForTemporaryFile(dir, path); 411 int fd = CreateAndOpenFdForTemporaryFile(dir, path);
397 if (fd < 0) 412 if (fd < 0)
398 return NULL; 413 return NULL;
399 414
400 return fdopen(fd, "a+"); 415 return fdopen(fd, "a+");
401 } 416 }
402 417
403 bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { 418 bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) {
419 base::ThreadRestrictions::AssertIOAllowed(); // For call to close().
404 int fd = CreateAndOpenFdForTemporaryFile(dir, temp_file); 420 int fd = CreateAndOpenFdForTemporaryFile(dir, temp_file);
405 return ((fd >= 0) && !close(fd)); 421 return ((fd >= 0) && !close(fd));
406 } 422 }
407 423
408 static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir, 424 static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir,
409 const FilePath::StringType& name_tmpl, 425 const FilePath::StringType& name_tmpl,
410 FilePath* new_dir) { 426 FilePath* new_dir) {
427 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdtemp().
411 CHECK(name_tmpl.find("XXXXXX") != FilePath::StringType::npos) 428 CHECK(name_tmpl.find("XXXXXX") != FilePath::StringType::npos)
412 << "Directory name template must contain \"XXXXXX\"."; 429 << "Directory name template must contain \"XXXXXX\".";
413 430
414 FilePath sub_dir = base_dir.Append(name_tmpl); 431 FilePath sub_dir = base_dir.Append(name_tmpl);
415 std::string sub_dir_string = sub_dir.value(); 432 std::string sub_dir_string = sub_dir.value();
416 433
417 // this should be OK since mkdtemp just replaces characters in place 434 // this should be OK since mkdtemp just replaces characters in place
418 char* buffer = const_cast<char*>(sub_dir_string.c_str()); 435 char* buffer = const_cast<char*>(sub_dir_string.c_str());
419 char* dtemp = mkdtemp(buffer); 436 char* dtemp = mkdtemp(buffer);
420 if (!dtemp) { 437 if (!dtemp) {
(...skipping 15 matching lines...) Expand all
436 bool CreateNewTempDirectory(const FilePath::StringType& prefix, 453 bool CreateNewTempDirectory(const FilePath::StringType& prefix,
437 FilePath* new_temp_path) { 454 FilePath* new_temp_path) {
438 FilePath tmpdir; 455 FilePath tmpdir;
439 if (!GetTempDir(&tmpdir)) 456 if (!GetTempDir(&tmpdir))
440 return false; 457 return false;
441 458
442 return CreateTemporaryDirInDirImpl(tmpdir, kTempFileName, new_temp_path); 459 return CreateTemporaryDirInDirImpl(tmpdir, kTempFileName, new_temp_path);
443 } 460 }
444 461
445 bool CreateDirectory(const FilePath& full_path) { 462 bool CreateDirectory(const FilePath& full_path) {
463 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdir().
446 std::vector<FilePath> subpaths; 464 std::vector<FilePath> subpaths;
447 465
448 // Collect a list of all parent directories. 466 // Collect a list of all parent directories.
449 FilePath last_path = full_path; 467 FilePath last_path = full_path;
450 subpaths.push_back(full_path); 468 subpaths.push_back(full_path);
451 for (FilePath path = full_path.DirName(); 469 for (FilePath path = full_path.DirName();
452 path.value() != last_path.value(); path = path.DirName()) { 470 path.value() != last_path.value(); path = path.DirName()) {
453 subpaths.push_back(path); 471 subpaths.push_back(path);
454 last_path = path; 472 last_path = path;
455 } 473 }
(...skipping 21 matching lines...) Expand all
477 return false; 495 return false;
478 results->is_directory = S_ISDIR(file_info.st_mode); 496 results->is_directory = S_ISDIR(file_info.st_mode);
479 results->size = file_info.st_size; 497 results->size = file_info.st_size;
480 results->last_modified = base::Time::FromTimeT(file_info.st_mtime); 498 results->last_modified = base::Time::FromTimeT(file_info.st_mtime);
481 results->last_accessed = base::Time::FromTimeT(file_info.st_atime); 499 results->last_accessed = base::Time::FromTimeT(file_info.st_atime);
482 results->creation_time = base::Time::FromTimeT(file_info.st_ctime); 500 results->creation_time = base::Time::FromTimeT(file_info.st_ctime);
483 return true; 501 return true;
484 } 502 }
485 503
486 bool GetInode(const FilePath& path, ino_t* inode) { 504 bool GetInode(const FilePath& path, ino_t* inode) {
505 base::ThreadRestrictions::AssertIOAllowed(); // For call to stat().
487 struct stat buffer; 506 struct stat buffer;
488 int result = stat(path.value().c_str(), &buffer); 507 int result = stat(path.value().c_str(), &buffer);
489 if (result < 0) 508 if (result < 0)
490 return false; 509 return false;
491 510
492 *inode = buffer.st_ino; 511 *inode = buffer.st_ino;
493 return true; 512 return true;
494 } 513 }
495 514
496 FILE* OpenFile(const std::string& filename, const char* mode) { 515 FILE* OpenFile(const std::string& filename, const char* mode) {
497 return OpenFile(FilePath(filename), mode); 516 return OpenFile(FilePath(filename), mode);
498 } 517 }
499 518
500 FILE* OpenFile(const FilePath& filename, const char* mode) { 519 FILE* OpenFile(const FilePath& filename, const char* mode) {
520 base::ThreadRestrictions::AssertIOAllowed();
501 return fopen(filename.value().c_str(), mode); 521 return fopen(filename.value().c_str(), mode);
502 } 522 }
503 523
504 int ReadFile(const FilePath& filename, char* data, int size) { 524 int ReadFile(const FilePath& filename, char* data, int size) {
525 base::ThreadRestrictions::AssertIOAllowed();
505 int fd = open(filename.value().c_str(), O_RDONLY); 526 int fd = open(filename.value().c_str(), O_RDONLY);
506 if (fd < 0) 527 if (fd < 0)
507 return -1; 528 return -1;
508 529
509 ssize_t bytes_read = HANDLE_EINTR(read(fd, data, size)); 530 ssize_t bytes_read = HANDLE_EINTR(read(fd, data, size));
510 if (int ret = HANDLE_EINTR(close(fd)) < 0) 531 if (int ret = HANDLE_EINTR(close(fd)) < 0)
511 return ret; 532 return ret;
512 return bytes_read; 533 return bytes_read;
513 } 534 }
514 535
515 int WriteFile(const FilePath& filename, const char* data, int size) { 536 int WriteFile(const FilePath& filename, const char* data, int size) {
537 base::ThreadRestrictions::AssertIOAllowed();
516 int fd = creat(filename.value().c_str(), 0666); 538 int fd = creat(filename.value().c_str(), 0666);
517 if (fd < 0) 539 if (fd < 0)
518 return -1; 540 return -1;
519 541
520 int bytes_written = WriteFileDescriptor(fd, data, size); 542 int bytes_written = WriteFileDescriptor(fd, data, size);
521 if (int ret = HANDLE_EINTR(close(fd)) < 0) 543 if (int ret = HANDLE_EINTR(close(fd)) < 0)
522 return ret; 544 return ret;
523 return bytes_written; 545 return bytes_written;
524 } 546 }
525 547
526 int WriteFileDescriptor(const int fd, const char* data, int size) { 548 int WriteFileDescriptor(const int fd, const char* data, int size) {
527 // Allow for partial writes. 549 // Allow for partial writes.
528 ssize_t bytes_written_total = 0; 550 ssize_t bytes_written_total = 0;
529 for (ssize_t bytes_written_partial = 0; bytes_written_total < size; 551 for (ssize_t bytes_written_partial = 0; bytes_written_total < size;
530 bytes_written_total += bytes_written_partial) { 552 bytes_written_total += bytes_written_partial) {
531 bytes_written_partial = 553 bytes_written_partial =
532 HANDLE_EINTR(write(fd, data + bytes_written_total, 554 HANDLE_EINTR(write(fd, data + bytes_written_total,
533 size - bytes_written_total)); 555 size - bytes_written_total));
534 if (bytes_written_partial < 0) 556 if (bytes_written_partial < 0)
535 return -1; 557 return -1;
536 } 558 }
537 559
538 return bytes_written_total; 560 return bytes_written_total;
539 } 561 }
540 562
541 // Gets the current working directory for the process. 563 // Gets the current working directory for the process.
542 bool GetCurrentDirectory(FilePath* dir) { 564 bool GetCurrentDirectory(FilePath* dir) {
565 // getcwd can return ENOENT, which implies it checks against the disk.
566 base::ThreadRestrictions::AssertIOAllowed();
567
543 char system_buffer[PATH_MAX] = ""; 568 char system_buffer[PATH_MAX] = "";
544 if (!getcwd(system_buffer, sizeof(system_buffer))) { 569 if (!getcwd(system_buffer, sizeof(system_buffer))) {
545 NOTREACHED(); 570 NOTREACHED();
546 return false; 571 return false;
547 } 572 }
548 *dir = FilePath(system_buffer); 573 *dir = FilePath(system_buffer);
549 return true; 574 return true;
550 } 575 }
551 576
552 // Sets the current working directory for the process. 577 // Sets the current working directory for the process.
553 bool SetCurrentDirectory(const FilePath& path) { 578 bool SetCurrentDirectory(const FilePath& path) {
579 base::ThreadRestrictions::AssertIOAllowed();
554 int ret = chdir(path.value().c_str()); 580 int ret = chdir(path.value().c_str());
555 return !ret; 581 return !ret;
556 } 582 }
557 583
558 /////////////////////////////////////////////// 584 ///////////////////////////////////////////////
559 // FileEnumerator 585 // FileEnumerator
560 586
561 FileEnumerator::FileEnumerator(const FilePath& root_path, 587 FileEnumerator::FileEnumerator(const FilePath& root_path,
562 bool recursive, 588 bool recursive,
563 FileEnumerator::FILE_TYPE file_type) 589 FileEnumerator::FILE_TYPE file_type)
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 directory_entries_.push_back(*i); 674 directory_entries_.push_back(*i);
649 } 675 }
650 } 676 }
651 677
652 return root_path_.Append(directory_entries_[current_directory_entry_ 678 return root_path_.Append(directory_entries_[current_directory_entry_
653 ].filename); 679 ].filename);
654 } 680 }
655 681
656 bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, 682 bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries,
657 const FilePath& source, bool show_links) { 683 const FilePath& source, bool show_links) {
684 base::ThreadRestrictions::AssertIOAllowed();
658 DIR* dir = opendir(source.value().c_str()); 685 DIR* dir = opendir(source.value().c_str());
659 if (!dir) 686 if (!dir)
660 return false; 687 return false;
661 688
662 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ 689 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \
663 !defined(OS_OPENBSD) && !defined(OS_SOLARIS) 690 !defined(OS_OPENBSD) && !defined(OS_SOLARIS)
664 #error Port warning: depending on the definition of struct dirent, \ 691 #error Port warning: depending on the definition of struct dirent, \
665 additional space for pathname may be needed 692 additional space for pathname may be needed
666 #endif 693 #endif
667 694
(...skipping 28 matching lines...) Expand all
696 /////////////////////////////////////////////// 723 ///////////////////////////////////////////////
697 // MemoryMappedFile 724 // MemoryMappedFile
698 725
699 MemoryMappedFile::MemoryMappedFile() 726 MemoryMappedFile::MemoryMappedFile()
700 : file_(base::kInvalidPlatformFileValue), 727 : file_(base::kInvalidPlatformFileValue),
701 data_(NULL), 728 data_(NULL),
702 length_(0) { 729 length_(0) {
703 } 730 }
704 731
705 bool MemoryMappedFile::MapFileToMemoryInternal() { 732 bool MemoryMappedFile::MapFileToMemoryInternal() {
733 base::ThreadRestrictions::AssertIOAllowed();
734
706 struct stat file_stat; 735 struct stat file_stat;
707 if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) { 736 if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) {
708 LOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno; 737 LOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno;
709 return false; 738 return false;
710 } 739 }
711 length_ = file_stat.st_size; 740 length_ = file_stat.st_size;
712 741
713 data_ = static_cast<uint8*>( 742 data_ = static_cast<uint8*>(
714 mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0)); 743 mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0));
715 if (data_ == MAP_FAILED) 744 if (data_ == MAP_FAILED)
716 LOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno; 745 LOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno;
717 746
718 return data_ != MAP_FAILED; 747 return data_ != MAP_FAILED;
719 } 748 }
720 749
721 void MemoryMappedFile::CloseHandles() { 750 void MemoryMappedFile::CloseHandles() {
751 base::ThreadRestrictions::AssertIOAllowed();
752
722 if (data_ != NULL) 753 if (data_ != NULL)
723 munmap(data_, length_); 754 munmap(data_, length_);
724 if (file_ != base::kInvalidPlatformFileValue) 755 if (file_ != base::kInvalidPlatformFileValue)
725 close(file_); 756 close(file_);
726 757
727 data_ = NULL; 758 data_ = NULL;
728 length_ = 0; 759 length_ = 0;
729 file_ = base::kInvalidPlatformFileValue; 760 file_ = base::kInvalidPlatformFileValue;
730 } 761 }
731 762
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 bool GetShmemTempDir(FilePath* path) { 794 bool GetShmemTempDir(FilePath* path) {
764 *path = FilePath("/dev/shm"); 795 *path = FilePath("/dev/shm");
765 return true; 796 return true;
766 } 797 }
767 798
768 FilePath GetHomeDir() { 799 FilePath GetHomeDir() {
769 const char* home_dir = getenv("HOME"); 800 const char* home_dir = getenv("HOME");
770 if (home_dir && home_dir[0]) 801 if (home_dir && home_dir[0])
771 return FilePath(home_dir); 802 return FilePath(home_dir);
772 803
804 // g_get_home_dir calls getpwent, which can fall through to LDAP calls.
805 base::ThreadRestrictions::AssertIOAllowed();
806
773 home_dir = g_get_home_dir(); 807 home_dir = g_get_home_dir();
774 if (home_dir && home_dir[0]) 808 if (home_dir && home_dir[0])
775 return FilePath(home_dir); 809 return FilePath(home_dir);
776 810
777 FilePath rv; 811 FilePath rv;
778 if (file_util::GetTempDir(&rv)) 812 if (file_util::GetTempDir(&rv))
779 return rv; 813 return rv;
780 814
781 // Last resort. 815 // Last resort.
782 return FilePath("/tmp"); 816 return FilePath("/tmp");
783 } 817 }
784 818
785 bool CopyFile(const FilePath& from_path, const FilePath& to_path) { 819 bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
820 base::ThreadRestrictions::AssertIOAllowed();
786 int infile = open(from_path.value().c_str(), O_RDONLY); 821 int infile = open(from_path.value().c_str(), O_RDONLY);
787 if (infile < 0) 822 if (infile < 0)
788 return false; 823 return false;
789 824
790 int outfile = creat(to_path.value().c_str(), 0666); 825 int outfile = creat(to_path.value().c_str(), 0666);
791 if (outfile < 0) { 826 if (outfile < 0) {
792 close(infile); 827 close(infile);
793 return false; 828 return false;
794 } 829 }
795 830
(...skipping 27 matching lines...) Expand all
823 if (HANDLE_EINTR(close(infile)) < 0) 858 if (HANDLE_EINTR(close(infile)) < 0)
824 result = false; 859 result = false;
825 if (HANDLE_EINTR(close(outfile)) < 0) 860 if (HANDLE_EINTR(close(outfile)) < 0)
826 result = false; 861 result = false;
827 862
828 return result; 863 return result;
829 } 864 }
830 #endif // defined(OS_MACOSX) 865 #endif // defined(OS_MACOSX)
831 866
832 } // namespace file_util 867 } // namespace file_util
OLDNEW
« no previous file with comments | « no previous file | base/shared_memory_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698