| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bin/directory.h" | 5 #include "bin/directory.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include "bin/platform.h" | 10 #include "bin/platform.h" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 static bool DeleteFile(char* file_name, | 191 static bool DeleteFile(char* file_name, |
| 192 char* path, | 192 char* path, |
| 193 int path_length) { | 193 int path_length) { |
| 194 size_t written = snprintf(path + path_length, | 194 size_t written = snprintf(path + path_length, |
| 195 MAX_PATH - path_length, | 195 MAX_PATH - path_length, |
| 196 "%s", | 196 "%s", |
| 197 file_name); | 197 file_name); |
| 198 if (written != strlen(file_name)) { | 198 if (written != strlen(file_name)) { |
| 199 return false; | 199 return false; |
| 200 } | 200 } |
| 201 return (DeleteFile(path) != 0); | 201 |
| 202 if (DeleteFile(path) != 0) { |
| 203 return true; |
| 204 } |
| 205 |
| 206 // If we failed because the file is read-only, make it writeable and try |
| 207 // again. This mirrors Linux/Mac where a directory containing read-only files |
| 208 // can still be recursively deleted. |
| 209 if (GetLastError() == ERROR_ACCESS_DENIED) { |
| 210 DWORD attributes = GetFileAttributes(path); |
| 211 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 212 return false; |
| 213 } |
| 214 |
| 215 if ((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { |
| 216 attributes &= ~FILE_ATTRIBUTE_READONLY; |
| 217 |
| 218 if (SetFileAttributes(path, attributes) == 0) { |
| 219 return false; |
| 220 } |
| 221 |
| 222 return DeleteFile(path) != 0; |
| 223 } |
| 224 } |
| 202 } | 225 } |
| 203 | 226 |
| 204 | 227 |
| 205 static bool DeleteDir(char* dir_name, | 228 static bool DeleteDir(char* dir_name, |
| 206 char* path, | 229 char* path, |
| 207 int path_length) { | 230 int path_length) { |
| 208 if (strcmp(dir_name, ".") != 0 && | 231 if (strcmp(dir_name, ".") != 0 && |
| 209 strcmp(dir_name, "..") != 0) { | 232 strcmp(dir_name, "..") != 0) { |
| 210 size_t written = snprintf(path + path_length, | 233 size_t written = snprintf(path + path_length, |
| 211 MAX_PATH - path_length, | 234 MAX_PATH - path_length, |
| 212 "%s", | 235 "%s", |
| 213 dir_name); | 236 dir_name); |
| 214 if (written != strlen(dir_name)) { | 237 if (written != strlen(dir_name)) { |
| 215 return false; | 238 return false; |
| 216 } | 239 } |
| 217 return DeleteRecursively(path); | 240 return DeleteRecursively(path); |
| 218 } | 241 } |
| 219 return true; | 242 return true; |
| 220 } | 243 } |
| 221 | 244 |
| 222 | 245 |
| 223 static bool DeleteEntry(LPWIN32_FIND_DATA find_file_data, | 246 static bool DeleteEntry(LPWIN32_FIND_DATA find_file_data, |
| 224 char* path, | 247 char* path, |
| 225 int path_length) { | 248 int path_length) { |
| 226 DWORD attributes = find_file_data->dwFileAttributes; | 249 DWORD attributes = find_file_data->dwFileAttributes; |
| 250 |
| 227 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 251 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 228 return DeleteDir(find_file_data->cFileName, path, path_length); | 252 return DeleteDir(find_file_data->cFileName, path, path_length); |
| 229 } else { | 253 } else { |
| 230 return DeleteFile(find_file_data->cFileName, path, path_length); | 254 return DeleteFile(find_file_data->cFileName, path, path_length); |
| 231 } | 255 } |
| 232 } | 256 } |
| 233 | 257 |
| 234 | 258 |
| 235 static bool DeleteRecursively(const char* dir_name) { | 259 static bool DeleteRecursively(const char* dir_name) { |
| 236 // If the directory is a junction, it's pointing to some other place in the | 260 // If the directory is a junction, it's pointing to some other place in the |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 // MoveFile does not allow replacing exising directories. Therefore, | 424 // MoveFile does not allow replacing exising directories. Therefore, |
| 401 // if the new_path is currently a directory we need to delete it | 425 // if the new_path is currently a directory we need to delete it |
| 402 // first. | 426 // first. |
| 403 if (new_exists == EXISTS) { | 427 if (new_exists == EXISTS) { |
| 404 bool success = DeleteRecursively(new_path); | 428 bool success = DeleteRecursively(new_path); |
| 405 if (!success) return false; | 429 if (!success) return false; |
| 406 } | 430 } |
| 407 DWORD flags = MOVEFILE_WRITE_THROUGH; | 431 DWORD flags = MOVEFILE_WRITE_THROUGH; |
| 408 return (MoveFileEx(path, new_path, flags) != 0); | 432 return (MoveFileEx(path, new_path, flags) != 0); |
| 409 } | 433 } |
| OLD | NEW |