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

Unified Diff: runtime/bin/directory_win.cc

Issue 13654002: Change how File/Directory/Link .delete works. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix windows error codes. Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: runtime/bin/directory_win.cc
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index d4b0aafa6d2bebed3e53f598f40afcc0f6eac44b..7ee9b593cd22a2fadd8af116b85a769821503a0c 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -6,6 +6,7 @@
#if defined(TARGET_OS_WINDOWS)
#include "bin/directory.h"
+#include "bin/file.h"
#include <errno.h> // NOLINT
#include <sys/stat.h> // NOLINT
@@ -48,6 +49,25 @@ class PathBuffer {
}
};
+// If link_name points to a link, IsBrokenLink will return true if link_name
+// points to an invalid target.
+static bool IsBrokenLink(const wchar_t* link_name) {
+ HANDLE handle = CreateFileW(
+ link_name,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return true;
+ } else {
+ CloseHandle(handle);
+ return false;
+ }
+}
+
// Forward declarations.
static bool ListRecursively(PathBuffer* path,
@@ -122,18 +142,13 @@ static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
if (!follow_links) {
return HandleLink(find_file_data->cFileName, path, listing);
}
- // Attempt to list the directory, to see if it's a valid link or not.
int path_length = path->length;
if (!path->Add(find_file_data->cFileName)) return false;
- if (!path->Add(L"\\*")) return false;
- WIN32_FIND_DATAW tmp_file_data;
- HANDLE find_handle = FindFirstFileW(path->data, &tmp_file_data);
+ bool broken = IsBrokenLink(path->data);
path->Reset(path_length);
- if (find_handle == INVALID_HANDLE_VALUE) {
- // Invalid handle, report as (broken) link.
+ if (broken) {
+ // Report as (broken) link.
return HandleLink(find_file_data->cFileName, path, listing);
- } else {
- FindClose(find_handle);
}
}
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
@@ -253,8 +268,12 @@ static bool DeleteRecursively(PathBuffer* path) {
DWORD attributes = GetFileAttributesW(path->data);
if ((attributes != INVALID_FILE_ATTRIBUTES) &&
(attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
- // Just delete the junction itself.
- return RemoveDirectoryW(path->data) != 0;
+ if (IsBrokenLink(path->data)) {
+ return false;
+ } else {
+ // Just delete the junction itself.
+ return RemoveDirectoryW(path->data) != 0;
+ }
}
if (!path->Add(L"\\*")) return false;
@@ -318,6 +337,7 @@ static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) {
}
}
bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+ exists = exists && !IsBrokenLink(dir_name);
return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST;
}
@@ -407,13 +427,16 @@ bool Directory::Delete(const char* dir_name, bool recursive) {
bool result = false;
const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name);
if (!recursive) {
- result = (RemoveDirectoryW(system_dir_name) != 0);
+ if (File::GetType(dir_name, true) == File::kIsDirectory) {
+ result = (RemoveDirectoryW(system_dir_name) != 0);
+ } else {
+ SetLastError(ERROR_DIRECTORY);
+ }
} else {
PathBuffer path;
- if (!path.Add(system_dir_name)) {
- return false;
+ if (path.Add(system_dir_name)) {
+ result = DeleteRecursively(&path);
}
- result = DeleteRecursively(&path);
}
free(const_cast<wchar_t*>(system_dir_name));
return result;
« no previous file with comments | « runtime/bin/directory_macos.cc ('k') | runtime/bin/file.h » ('j') | runtime/bin/file_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698