diff options
author | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-31 19:30:27 +0000 |
---|---|---|
committer | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-31 19:30:27 +0000 |
commit | ed65fece343181e91b4d36e161434cc763475de7 (patch) | |
tree | 27af7d7cb8a12f65b24dba3ebd5ede3d592e2d8e /base | |
parent | 2d723bc66e60bedd617ebd464996ee2388c0c365 (diff) | |
download | chromium_src-ed65fece343181e91b4d36e161434cc763475de7.zip chromium_src-ed65fece343181e91b4d36e161434cc763475de7.tar.gz chromium_src-ed65fece343181e91b4d36e161434cc763475de7.tar.bz2 |
Add an optional parameter to CreatePlatformFile() to report the type
of error that occured while trying to open/create a file.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/3223007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58045 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/file_util.cc | 6 | ||||
-rw-r--r-- | base/file_util_proxy.cc | 33 | ||||
-rw-r--r-- | base/file_util_proxy.h | 11 | ||||
-rw-r--r-- | base/platform_file.h | 22 | ||||
-rw-r--r-- | base/platform_file_posix.cc | 48 | ||||
-rw-r--r-- | base/platform_file_win.cc | 32 |
6 files changed, 117 insertions, 35 deletions
diff --git a/base/file_util.cc b/base/file_util.cc index edf8e69..4dae03b 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -320,9 +320,9 @@ bool MemoryMappedFile::Initialize(const FilePath& file_name) { } bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { - file_ = base::CreatePlatformFile(file_name, - base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, - NULL); + file_ = base::CreatePlatformFile( + file_name, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, + NULL, NULL); if (file_ == base::kInvalidPlatformFileValue) { LOG(ERROR) << "Couldn't open " << file_name.value(); diff --git a/base/file_util_proxy.cc b/base/file_util_proxy.cc index 3863b37..de16b10 100644 --- a/base/file_util_proxy.cc +++ b/base/file_util_proxy.cc @@ -37,11 +37,11 @@ class MessageLoopRelay // Called to notify the callback on the origin thread. virtual void RunCallback() = 0; - void set_error_code(int error_code) { + void set_error_code(base::PlatformFileError error_code) { error_code_ = error_code; } - int error_code() const { + base::PlatformFileError error_code() const { return error_code_; } @@ -54,7 +54,7 @@ class MessageLoopRelay } scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; - int error_code_; + base::PlatformFileError error_code_; }; class RelayCreateOrOpen : public MessageLoopRelay { @@ -80,9 +80,10 @@ class RelayCreateOrOpen : public MessageLoopRelay { } virtual void RunWork() { - file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, &created_); - if (file_handle_ == base::kInvalidPlatformFileValue) - set_error_code(base::PLATFORM_FILE_ERROR); + base::PlatformFileError error_code = base::PLATFORM_FILE_OK; + file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, + &created_, &error_code); + set_error_code(error_code); } virtual void RunCallback() { @@ -129,9 +130,10 @@ class RelayCreateTemporary : public MessageLoopRelay { base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC | base::PLATFORM_FILE_TEMPORARY; - file_handle_ = base::CreatePlatformFile(file_path_, file_flags, NULL); - if (file_handle_ == base::kInvalidPlatformFileValue) - set_error_code(base::PLATFORM_FILE_ERROR); + base::PlatformFileError error_code = base::PLATFORM_FILE_OK; + file_handle_ = base::CreatePlatformFile(file_path_, file_flags, + NULL, &error_code); + set_error_code(error_code); } virtual void RunCallback() { @@ -179,7 +181,7 @@ class RelayClose : public RelayWithStatusCallback { protected: virtual void RunWork() { if (!base::ClosePlatformFile(file_handle_)) - set_error_code(base::PLATFORM_FILE_ERROR); + set_error_code(base::PLATFORM_FILE_ERROR_FAILED); } private: @@ -199,7 +201,7 @@ class RelayDelete : public RelayWithStatusCallback { protected: virtual void RunWork() { if (!file_util::Delete(file_path_, recursive_)) - set_error_code(base::PLATFORM_FILE_ERROR); + set_error_code(base::PLATFORM_FILE_ERROR_FAILED); } private: @@ -212,25 +214,24 @@ class RelayGetFileInfo : public MessageLoopRelay { RelayGetFileInfo(const FilePath& file_path, base::FileUtilProxy::GetFileInfoCallback* callback) : callback_(callback), - file_path_(file_path), - exists_(false) { + file_path_(file_path) { DCHECK(callback); } protected: virtual void RunWork() { - exists_ = file_util::GetFileInfo(file_path_, &file_info_); + if (!file_util::GetFileInfo(file_path_, &file_info_)) + set_error_code(base::PLATFORM_FILE_ERROR_FAILED); } virtual void RunCallback() { - callback_->Run(exists_, file_info_); + callback_->Run(error_code(), file_info_); delete callback_; } private: base::FileUtilProxy::GetFileInfoCallback* callback_; FilePath file_path_; - bool exists_; file_util::FileInfo file_info_; }; diff --git a/base/file_util_proxy.h b/base/file_util_proxy.h index ff04e5b..9899c77 100644 --- a/base/file_util_proxy.h +++ b/base/file_util_proxy.h @@ -24,11 +24,13 @@ class FileUtilProxy { // This callback is used by methods that report only an error code. It is // valid to pass NULL as the callback parameter to any function that takes a // StatusCallback, in which case the operation will complete silently. - typedef Callback1<int /* error code */>::Type StatusCallback; + typedef Callback1<base::PlatformFileError /* error code */ + >::Type StatusCallback; // Creates or opens a file with the given flags. It is invalid to pass NULL // for the callback. - typedef Callback3<int /* error code */, base::PassPlatformFile, + typedef Callback3<base::PlatformFileError /* error code */, + base::PassPlatformFile, bool /* created */>::Type CreateOrOpenCallback; static bool CreateOrOpen(scoped_refptr<MessageLoopProxy> message_loop_proxy, const FilePath& file_path, @@ -37,7 +39,8 @@ class FileUtilProxy { // Creates a temporary file for writing. The path and an open file handle // are returned. It is invalid to pass NULL for the callback. - typedef Callback3<int /* error code */, base::PassPlatformFile, + typedef Callback3<base::PlatformFileError /* error code */, + base::PassPlatformFile, FilePath>::Type CreateTemporaryCallback; static bool CreateTemporary( scoped_refptr<MessageLoopProxy> message_loop_proxy, @@ -61,7 +64,7 @@ class FileUtilProxy { // Retrieves the information about a file. It is invalid to pass NULL for the // callback. - typedef Callback2<bool /*exists*/, + typedef Callback2<base::PlatformFileError /* error code */, const file_util::FileInfo& /*file_info*/ >::Type GetFileInfoCallback; static bool GetFileInfo( diff --git a/base/platform_file.h b/base/platform_file.h index 0216c71..70ed0f1 100644 --- a/base/platform_file.h +++ b/base/platform_file.h @@ -37,22 +37,30 @@ enum PlatformFileFlags { PLATFORM_FILE_ASYNC = 256, PLATFORM_FILE_TEMPORARY = 512, // Used on Windows only PLATFORM_FILE_HIDDEN = 1024, // Used on Windows only - PLATFORM_FILE_DELETE_ON_CLOSE = 2048 + PLATFORM_FILE_DELETE_ON_CLOSE = 2048, + PLATFORM_FILE_TRUNCATE = 4096 }; -// TODO(dumi): add more specific error codes for CreatePlatformFile(). -// TODO(dumi): add more error codes as we add new methods to FileUtilProxy. -enum PlatformFileErrors { +enum PlatformFileError { PLATFORM_FILE_OK = 0, - PLATFORM_FILE_ERROR = -1 + PLATFORM_FILE_ERROR_FAILED = -1, + PLATFORM_FILE_ERROR_IN_USE = -2, + PLATFORM_FILE_ERROR_EXISTS = -3, + PLATFORM_FILE_ERROR_NOT_FOUND = -4, + PLATFORM_FILE_ERROR_ACCESS_DENIED = -5, + PLATFORM_FILE_ERROR_TOO_MANY_OPENED = -6, + PLATFORM_FILE_ERROR_NO_MEMORY = -7, + PLATFORM_FILE_ERROR_NO_SPACE = -7, + PLATFORM_FILE_ERROR_NOT_A_DIRECTORY = -9 }; // Creates or opens the given file. If PLATFORM_FILE_OPEN_ALWAYS is used, and // |created| is provided, |created| will be set to true if the file was created -// or to false in case the file was just opened. +// or to false in case the file was just opened. |error_code| can be NULL. PlatformFile CreatePlatformFile(const FilePath& name, int flags, - bool* created); + bool* created, + PlatformFileError* error_code); // Deprecated. PlatformFile CreatePlatformFile(const std::wstring& name, int flags, diff --git a/base/platform_file_posix.cc b/base/platform_file_posix.cc index 46039b9..1afb250 100644 --- a/base/platform_file_posix.cc +++ b/base/platform_file_posix.cc @@ -16,7 +16,7 @@ namespace base { // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here? PlatformFile CreatePlatformFile(const FilePath& name, int flags, - bool* created) { + bool* created, PlatformFileError* error_code) { int open_flags = 0; if (flags & PLATFORM_FILE_CREATE) open_flags = O_CREAT | O_EXCL; @@ -30,6 +30,8 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags, !(flags & PLATFORM_FILE_OPEN_ALWAYS)) { NOTREACHED(); errno = EOPNOTSUPP; + if (error_code) + *error_code = PLATFORM_FILE_ERROR_FAILED; return kInvalidPlatformFileValue; } @@ -41,6 +43,11 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags, NOTREACHED(); } + if (flags & PLATFORM_FILE_TRUNCATE) { + DCHECK(flags & PLATFORM_FILE_WRITE); + open_flags |= O_TRUNC; + } + DCHECK(O_RDONLY == 0); int descriptor = open(name.value().c_str(), open_flags, S_IRUSR | S_IWUSR); @@ -61,16 +68,51 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags, } } - if ((descriptor > 0) && (flags & PLATFORM_FILE_DELETE_ON_CLOSE)) { + if ((descriptor < 0) && (flags & PLATFORM_FILE_DELETE_ON_CLOSE)) { unlink(name.value().c_str()); } + if ((descriptor < 0) && error_code) { + switch (errno) { + case EACCES: + case EISDIR: + case EROFS: + case EPERM: + *error_code = PLATFORM_FILE_ERROR_ACCESS_DENIED; + break; + case ETXTBSY: + *error_code = PLATFORM_FILE_ERROR_IN_USE; + break; + case EEXIST: + *error_code = PLATFORM_FILE_ERROR_EXISTS; + break; + case ENOENT: + *error_code = PLATFORM_FILE_ERROR_NOT_FOUND; + break; + case EMFILE: + *error_code = PLATFORM_FILE_ERROR_TOO_MANY_OPENED; + break; + case ENOMEM: + *error_code = PLATFORM_FILE_ERROR_NO_MEMORY; + break; + case ENOSPC: + *error_code = PLATFORM_FILE_ERROR_NO_SPACE; + break; + case ENOTDIR: + *error_code = PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; + break; + default: + *error_code = PLATFORM_FILE_ERROR_FAILED; + } + } + return descriptor; } PlatformFile CreatePlatformFile(const std::wstring& name, int flags, bool* created) { - return CreatePlatformFile(FilePath::FromWStringHack(name), flags, created); + return CreatePlatformFile(FilePath::FromWStringHack(name), flags, + created, NULL); } bool ClosePlatformFile(PlatformFile file) { diff --git a/base/platform_file_win.cc b/base/platform_file_win.cc index 1143487..c4b3c08 100644 --- a/base/platform_file_win.cc +++ b/base/platform_file_win.cc @@ -11,7 +11,8 @@ namespace base { PlatformFile CreatePlatformFile(const FilePath& name, int flags, - bool* created) { + bool* created, + PlatformFileError* error_code) { DWORD disposition = 0; if (flags & PLATFORM_FILE_OPEN) @@ -32,6 +33,12 @@ PlatformFile CreatePlatformFile(const FilePath& name, disposition = CREATE_ALWAYS; } + if (flags & PLATFORM_FILE_TRUNCATE) { + DCHECK(!disposition); + DCHECK(flags & PLATFORM_FILE_WRITE); + disposition = TRUNCATE_EXISTING; + } + if (!disposition) { NOTREACHED(); return NULL; @@ -63,12 +70,33 @@ PlatformFile CreatePlatformFile(const FilePath& name, *created = (ERROR_ALREADY_EXISTS != GetLastError()); } + if ((file == kInvalidPlatformFileValue) && error_code) { + DWORD last_error = GetLastError(); + switch (last_error) { + case ERROR_SHARING_VIOLATION: + *error_code = PLATFORM_FILE_ERROR_IN_USE; + break; + case ERROR_FILE_EXISTS: + *error_code = PLATFORM_FILE_ERROR_EXISTS; + break; + case ERROR_FILE_NOT_FOUND: + *error_code = PLATFORM_FILE_ERROR_NOT_FOUND; + break; + case ERROR_ACCESS_DENIED: + *error_code = PLATFORM_FILE_ERROR_ACCESS_DENIED; + break; + default: + *error_code = PLATFORM_FILE_ERROR_FAILED; + } + } + return file; } PlatformFile CreatePlatformFile(const std::wstring& name, int flags, bool* created) { - return CreatePlatformFile(FilePath::FromWStringHack(name), flags, created); + return CreatePlatformFile(FilePath::FromWStringHack(name), flags, + created, NULL); } bool ClosePlatformFile(PlatformFile file) { |