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

Side by Side Diff: runtime/bin/directory_macos.cc

Issue 1781883002: Fixes some memory leaks in //runtime/bin (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix tests on Windows Created 4 years, 9 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
« no previous file with comments | « runtime/bin/directory_linux.cc ('k') | runtime/bin/directory_win.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) 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 "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_MACOS) 6 #if defined(TARGET_OS_MACOS)
7 7
8 #include "bin/directory.h" 8 #include "bin/directory.h"
9 9
10 #include <dirent.h> // NOLINT 10 #include <dirent.h> // NOLINT
11 #include <errno.h> // NOLINT 11 #include <errno.h> // NOLINT
12 #include <string.h> // NOLINT 12 #include <string.h> // NOLINT
13 #include <sys/param.h> // NOLINT 13 #include <sys/param.h> // NOLINT
14 #include <sys/stat.h> // NOLINT 14 #include <sys/stat.h> // NOLINT
15 #include <unistd.h> // NOLINT 15 #include <unistd.h> // NOLINT
16 16
17 #include "bin/dartutils.h"
17 #include "bin/file.h" 18 #include "bin/file.h"
18 #include "bin/platform.h" 19 #include "bin/platform.h"
19
20 #include "platform/signal_blocker.h" 20 #include "platform/signal_blocker.h"
21 21
22
23 namespace dart { 22 namespace dart {
24 namespace bin { 23 namespace bin {
25 24
25 PathBuffer::PathBuffer() : length_(0) {
26 data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
27 }
26 28
27 PathBuffer::PathBuffer() : length_(0) { 29
28 data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT 30 PathBuffer::~PathBuffer() {
31 free(data_);
29 } 32 }
30 33
34
31 bool PathBuffer::AddW(const wchar_t* name) { 35 bool PathBuffer::AddW(const wchar_t* name) {
32 UNREACHABLE(); 36 UNREACHABLE();
33 return false; 37 return false;
34 } 38 }
35 39
40
36 char* PathBuffer::AsString() const { 41 char* PathBuffer::AsString() const {
37 return reinterpret_cast<char*>(data_); 42 return reinterpret_cast<char*>(data_);
38 } 43 }
39 44
45
40 wchar_t* PathBuffer::AsStringW() const { 46 wchar_t* PathBuffer::AsStringW() const {
41 UNREACHABLE(); 47 UNREACHABLE();
42 return NULL; 48 return NULL;
43 } 49 }
44 50
51
52 const char* PathBuffer::AsScopedString() const {
53 return DartUtils::ScopedCopyCString(AsString());
54 }
55
56
45 bool PathBuffer::Add(const char* name) { 57 bool PathBuffer::Add(const char* name) {
46 char* data = AsString(); 58 char* data = AsString();
47 int written = snprintf(data + length_, 59 int written = snprintf(data + length_,
48 PATH_MAX - length_, 60 PATH_MAX - length_,
49 "%s", 61 "%s",
50 name); 62 name);
51 data[PATH_MAX] = '\0'; 63 data[PATH_MAX] = '\0';
52 if (written <= PATH_MAX - length_ && 64 if ((written <= PATH_MAX - length_) &&
53 written >= 0 && 65 (written >= 0) &&
54 static_cast<size_t>(written) == strlen(name)) { 66 (static_cast<size_t>(written) == strlen(name))) {
55 length_ += written; 67 length_ += written;
56 return true; 68 return true;
57 } else { 69 } else {
58 errno = ENAMETOOLONG; 70 errno = ENAMETOOLONG;
59 return false; 71 return false;
60 } 72 }
61 } 73 }
62 74
63 void PathBuffer::Reset(int new_length) { 75
76 void PathBuffer::Reset(intptr_t new_length) {
64 length_ = new_length; 77 length_ = new_length;
65 AsString()[length_] = '\0'; 78 AsString()[length_] = '\0';
66 } 79 }
67 80
68 81
69 // A linked list of symbolic links, with their unique file system identifiers. 82 // A linked list of symbolic links, with their unique file system identifiers.
70 // These are scanned to detect loops while doing a recursive directory listing. 83 // These are scanned to detect loops while doing a recursive directory listing.
71 struct LinkList { 84 struct LinkList {
72 dev_t dev; 85 dev_t dev;
73 ino_t ino; 86 ino_t ino;
74 LinkList* next; 87 LinkList* next;
75 }; 88 };
76 89
77 90
78 ListType DirectoryListingEntry::Next(DirectoryListing* listing) { 91 ListType DirectoryListingEntry::Next(DirectoryListing* listing) {
79 if (done_) { 92 if (done_) {
80 return kListDone; 93 return kListDone;
81 } 94 }
82 95
83 if (lister_ == 0) { 96 if (lister_ == 0) {
84 do { 97 do {
85 lister_ = reinterpret_cast<intptr_t>( 98 lister_ = reinterpret_cast<intptr_t>(
86 opendir(listing->path_buffer().AsString())); 99 opendir(listing->path_buffer().AsString()));
87 } while (lister_ == 0 && errno == EINTR); 100 } while ((lister_ == 0) && (errno == EINTR));
88 101
89 if (lister_ == 0) { 102 if (lister_ == 0) {
90 done_ = true; 103 done_ = true;
91 return kListError; 104 return kListError;
92 } 105 }
93 if (parent_ != NULL) { 106 if (parent_ != NULL) {
94 if (!listing->path_buffer().Add(File::PathSeparator())) { 107 if (!listing->path_buffer().Add(File::PathSeparator())) {
95 return kListError; 108 return kListError;
96 } 109 }
97 } 110 }
98 path_length_ = listing->path_buffer().length(); 111 path_length_ = listing->path_buffer().length();
99 } 112 }
100 // Reset. 113 // Reset.
101 listing->path_buffer().Reset(path_length_); 114 listing->path_buffer().Reset(path_length_);
102 ResetLink(); 115 ResetLink();
103 116
104 // Iterate the directory and post the directories and files to the 117 // Iterate the directory and post the directories and files to the
105 // ports. 118 // ports.
106 int status = 0; 119 int status = 0;
107 dirent entry; 120 dirent entry;
108 dirent* result; 121 dirent* result;
109 if ((status = NO_RETRY_EXPECTED(readdir_r(reinterpret_cast<DIR*>(lister_), 122 status = NO_RETRY_EXPECTED(readdir_r(
110 &entry, 123 reinterpret_cast<DIR*>(lister_), &entry, &result));
111 &result))) == 0 && 124 if ((status == 0) && (result != NULL)) {
112 result != NULL) {
113 if (!listing->path_buffer().Add(entry.d_name)) { 125 if (!listing->path_buffer().Add(entry.d_name)) {
114 done_ = true; 126 done_ = true;
115 return kListError; 127 return kListError;
116 } 128 }
117 switch (entry.d_type) { 129 switch (entry.d_type) {
118 case DT_DIR: 130 case DT_DIR:
119 if (strcmp(entry.d_name, ".") == 0) return Next(listing); 131 if ((strcmp(entry.d_name, ".") == 0) ||
120 if (strcmp(entry.d_name, "..") == 0) return Next(listing); 132 (strcmp(entry.d_name, "..") == 0)) {
133 return Next(listing);
134 }
121 return kListDirectory; 135 return kListDirectory;
122 case DT_REG: 136 case DT_REG:
123 return kListFile; 137 return kListFile;
124 case DT_LNK: 138 case DT_LNK:
125 if (!listing->follow_links()) { 139 if (!listing->follow_links()) {
126 return kListLink; 140 return kListLink;
127 } 141 }
128 // Else fall through to next case. 142 // Else fall through to next case.
129 // Fall through. 143 // Fall through.
130 case DT_UNKNOWN: { 144 case DT_UNKNOWN: {
131 // On some file systems the entry type is not determined by 145 // On some file systems the entry type is not determined by
132 // readdir_r. For those and for links we use stat to determine 146 // readdir_r. For those and for links we use stat to determine
133 // the actual entry type. Notice that stat returns the type of 147 // the actual entry type. Notice that stat returns the type of
134 // the file pointed to. 148 // the file pointed to.
135 struct stat entry_info; 149 struct stat entry_info;
136 int stat_success; 150 int stat_success;
137 stat_success = NO_RETRY_EXPECTED( 151 stat_success = NO_RETRY_EXPECTED(
138 lstat(listing->path_buffer().AsString(), &entry_info)); 152 lstat(listing->path_buffer().AsString(), &entry_info));
139 if (stat_success == -1) { 153 if (stat_success == -1) {
140 return kListError; 154 return kListError;
141 } 155 }
142 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) { 156 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) {
143 // Check to see if we are in a loop created by a symbolic link. 157 // Check to see if we are in a loop created by a symbolic link.
144 LinkList current_link = { entry_info.st_dev, 158 LinkList current_link = { entry_info.st_dev,
145 entry_info.st_ino, 159 entry_info.st_ino,
146 link_ }; 160 link_ };
147 LinkList* previous = link_; 161 LinkList* previous = link_;
148 while (previous != NULL) { 162 while (previous != NULL) {
149 if (previous->dev == current_link.dev && 163 if ((previous->dev == current_link.dev) &&
150 previous->ino == current_link.ino) { 164 (previous->ino == current_link.ino)) {
151 // Report the looping link as a link, rather than following it. 165 // Report the looping link as a link, rather than following it.
152 return kListLink; 166 return kListLink;
153 } 167 }
154 previous = previous->next; 168 previous = previous->next;
155 } 169 }
156 stat_success = NO_RETRY_EXPECTED( 170 stat_success = NO_RETRY_EXPECTED(
157 stat(listing->path_buffer().AsString(), &entry_info)); 171 stat(listing->path_buffer().AsString(), &entry_info));
158 if (stat_success == -1) { 172 if (stat_success == -1) {
159 // Report a broken link as a link, even if follow_links is true. 173 // Report a broken link as a link, even if follow_links is true.
160 return kListLink; 174 return kListLink;
161 } 175 }
162 if (S_ISDIR(entry_info.st_mode)) { 176 if (S_ISDIR(entry_info.st_mode)) {
163 // Recurse into the subdirectory with current_link added to the 177 // Recurse into the subdirectory with current_link added to the
164 // linked list of seen file system links. 178 // linked list of seen file system links.
165 link_ = new LinkList(current_link); 179 link_ = new LinkList(current_link);
166 if (strcmp(entry.d_name, ".") == 0) return Next(listing); 180 if ((strcmp(entry.d_name, ".") == 0) ||
167 if (strcmp(entry.d_name, "..") == 0) return Next(listing); 181 (strcmp(entry.d_name, "..") == 0)) {
182 return Next(listing);
183 }
168 return kListDirectory; 184 return kListDirectory;
169 } 185 }
170 } 186 }
171 if (S_ISDIR(entry_info.st_mode)) { 187 if (S_ISDIR(entry_info.st_mode)) {
172 if (strcmp(entry.d_name, ".") == 0) return Next(listing); 188 if ((strcmp(entry.d_name, ".") == 0) ||
173 if (strcmp(entry.d_name, "..") == 0) return Next(listing); 189 (strcmp(entry.d_name, "..") == 0)) {
190 return Next(listing);
191 }
174 return kListDirectory; 192 return kListDirectory;
175 } else if (S_ISREG(entry_info.st_mode)) { 193 } else if (S_ISREG(entry_info.st_mode)) {
176 return kListFile; 194 return kListFile;
177 } else if (S_ISLNK(entry_info.st_mode)) { 195 } else if (S_ISLNK(entry_info.st_mode)) {
178 return kListLink; 196 return kListLink;
179 } 197 }
180 } 198 }
181 199
182 default: 200 default:
183 break; 201 break;
(...skipping 12 matching lines...) Expand all
196 214
197 DirectoryListingEntry::~DirectoryListingEntry() { 215 DirectoryListingEntry::~DirectoryListingEntry() {
198 ResetLink(); 216 ResetLink();
199 if (lister_ != 0) { 217 if (lister_ != 0) {
200 closedir(reinterpret_cast<DIR*>(lister_)); 218 closedir(reinterpret_cast<DIR*>(lister_));
201 } 219 }
202 } 220 }
203 221
204 222
205 void DirectoryListingEntry::ResetLink() { 223 void DirectoryListingEntry::ResetLink() {
206 if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) { 224 if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
207 delete link_; 225 delete link_;
208 link_ = NULL; 226 link_ = NULL;
209 } 227 }
210 if (parent_ != NULL) { 228 if (parent_ != NULL) {
211 link_ = parent_->link_; 229 link_ = parent_->link_;
212 } 230 }
213 } 231 }
214 232
215 233
216 static bool DeleteRecursively(PathBuffer* path); 234 static bool DeleteRecursively(PathBuffer* path);
217 235
218 236
219 static bool DeleteFile(char* file_name, 237 static bool DeleteFile(char* file_name,
220 PathBuffer* path) { 238 PathBuffer* path) {
221 return path->Add(file_name) && unlink(path->AsString()) == 0; 239 return path->Add(file_name) && (unlink(path->AsString()) == 0);
222 } 240 }
223 241
224 242
225 static bool DeleteDir(char* dir_name, 243 static bool DeleteDir(char* dir_name,
226 PathBuffer* path) { 244 PathBuffer* path) {
227 if (strcmp(dir_name, ".") == 0) return true; 245 if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) {
228 if (strcmp(dir_name, "..") == 0) return true; 246 return true;
247 }
229 return path->Add(dir_name) && DeleteRecursively(path); 248 return path->Add(dir_name) && DeleteRecursively(path);
230 } 249 }
231 250
232 251
233 static bool DeleteRecursively(PathBuffer* path) { 252 static bool DeleteRecursively(PathBuffer* path) {
234 // Do not recurse into links for deletion. Instead delete the link. 253 // Do not recurse into links for deletion. Instead delete the link.
235 // If it's a file, delete it. 254 // If it's a file, delete it.
236 struct stat st; 255 struct stat st;
237 if (NO_RETRY_EXPECTED(lstat(path->AsString(), &st)) == -1) { 256 if (NO_RETRY_EXPECTED(lstat(path->AsString(), &st)) == -1) {
238 return false; 257 return false;
239 } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { 258 } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
240 return (unlink(path->AsString()) == 0); 259 return (unlink(path->AsString()) == 0);
241 } 260 }
242 261
243 if (!path->Add(File::PathSeparator())) return false; 262 if (!path->Add(File::PathSeparator())) {
263 return false;
264 }
244 265
245 // Not a link. Attempt to open as a directory and recurse into the 266 // Not a link. Attempt to open as a directory and recurse into the
246 // directory. 267 // directory.
247 DIR* dir_pointer; 268 DIR* dir_pointer;
248 do { 269 do {
249 dir_pointer = opendir(path->AsString()); 270 dir_pointer = opendir(path->AsString());
250 } while (dir_pointer == NULL && errno == EINTR); 271 } while ((dir_pointer == NULL) && (errno == EINTR));
251 if (dir_pointer == NULL) { 272 if (dir_pointer == NULL) {
252 return false; 273 return false;
253 } 274 }
254 275
255 // Iterate the directory and delete all files and directories. 276 // Iterate the directory and delete all files and directories.
256 int path_length = path->length(); 277 int path_length = path->length();
257 dirent entry; 278 dirent entry;
258 dirent* result; 279 dirent* result;
259 while (NO_RETRY_EXPECTED(readdir_r(dir_pointer, &entry, &result)) == 0) { 280 while (NO_RETRY_EXPECTED(readdir_r(dir_pointer, &entry, &result)) == 0) {
260 if (result == NULL) { 281 if (result == NULL) {
261 // End of directory. 282 // End of directory.
262 return NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0 && 283 return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) &&
263 NO_RETRY_EXPECTED(remove(path->AsString())) == 0; 284 (NO_RETRY_EXPECTED(remove(path->AsString())) == 0);
264 } 285 }
265 bool ok = false; 286 bool ok = false;
266 switch (entry.d_type) { 287 switch (entry.d_type) {
267 case DT_DIR: 288 case DT_DIR:
268 ok = DeleteDir(entry.d_name, path); 289 ok = DeleteDir(entry.d_name, path);
269 break; 290 break;
270 case DT_REG: 291 case DT_REG:
271 case DT_LNK: 292 case DT_LNK:
272 // Treat all links as files. This will delete the link which 293 // Treat all links as files. This will delete the link which
273 // is what we want no matter if the link target is a file or a 294 // is what we want no matter if the link target is a file or a
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 Directory::ExistsResult Directory::Exists(const char* dir_name) { 337 Directory::ExistsResult Directory::Exists(const char* dir_name) {
317 struct stat entry_info; 338 struct stat entry_info;
318 int success = NO_RETRY_EXPECTED(stat(dir_name, &entry_info)); 339 int success = NO_RETRY_EXPECTED(stat(dir_name, &entry_info));
319 if (success == 0) { 340 if (success == 0) {
320 if (S_ISDIR(entry_info.st_mode)) { 341 if (S_ISDIR(entry_info.st_mode)) {
321 return EXISTS; 342 return EXISTS;
322 } else { 343 } else {
323 return DOES_NOT_EXIST; 344 return DOES_NOT_EXIST;
324 } 345 }
325 } else { 346 } else {
326 if (errno == EACCES || 347 if ((errno == EACCES) ||
327 errno == EBADF || 348 (errno == EBADF) ||
328 errno == EFAULT || 349 (errno == EFAULT) ||
329 errno == ENOMEM || 350 (errno == ENOMEM) ||
330 errno == EOVERFLOW) { 351 (errno == EOVERFLOW)) {
331 // Search permissions denied for one of the directories in the 352 // Search permissions denied for one of the directories in the
332 // path or a low level error occured. We do not know if the 353 // path or a low level error occured. We do not know if the
333 // directory exists. 354 // directory exists.
334 return UNKNOWN; 355 return UNKNOWN;
335 } 356 }
336 ASSERT(errno == ELOOP || 357 ASSERT((errno == ELOOP) ||
337 errno == ENAMETOOLONG || 358 (errno == ENAMETOOLONG) ||
338 errno == ENOENT || 359 (errno == ENOENT) ||
339 errno == ENOTDIR); 360 (errno == ENOTDIR));
340 return DOES_NOT_EXIST; 361 return DOES_NOT_EXIST;
341 } 362 }
342 } 363 }
343 364
344 365
345 char* Directory::Current() { 366 char* Directory::CurrentNoScope() {
346 return getcwd(NULL, 0); 367 return getcwd(NULL, 0);
347 } 368 }
348 369
349 370
371 const char* Directory::Current() {
372 char* result = DartUtils::ScopedCString(PATH_MAX);
373 ASSERT(result != NULL);
374 return getcwd(result, PATH_MAX);
375 }
376
377
350 bool Directory::SetCurrent(const char* path) { 378 bool Directory::SetCurrent(const char* path) {
351 int result = NO_RETRY_EXPECTED(chdir(path)); 379 int result = NO_RETRY_EXPECTED(chdir(path));
352 return result == 0; 380 return result == 0;
353 } 381 }
354 382
355 383
356 bool Directory::Create(const char* dir_name) { 384 bool Directory::Create(const char* dir_name) {
357 // Create the directory with the permissions specified by the 385 // Create the directory with the permissions specified by the
358 // process umask. 386 // process umask.
359 int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777)); 387 int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
360 // If the directory already exists, treat it as a success. 388 // If the directory already exists, treat it as a success.
361 if (result == -1 && errno == EEXIST) { 389 if ((result == -1) && (errno == EEXIST)) {
362 return (Exists(dir_name) == EXISTS); 390 return (Exists(dir_name) == EXISTS);
363 } 391 }
364 return (result == 0); 392 return (result == 0);
365 } 393 }
366 394
367 395
368 char* Directory::SystemTemp() { 396 const char* Directory::SystemTemp() {
397 PathBuffer path;
369 const char* temp_dir = getenv("TMPDIR"); 398 const char* temp_dir = getenv("TMPDIR");
370 if (temp_dir == NULL) { 399 if (temp_dir == NULL) {
371 temp_dir = getenv("TMP"); 400 temp_dir = getenv("TMP");
372 } 401 }
373 if (temp_dir == NULL) { 402 if (temp_dir == NULL) {
374 temp_dir = "/tmp"; 403 temp_dir = "/tmp";
375 } 404 }
376 char* result = strdup(temp_dir); 405 if (!path.Add(temp_dir)) {
406 return NULL;
407 }
377 // Remove any trailing slash. 408 // Remove any trailing slash.
409 char* result = path.AsString();
378 int length = strlen(result); 410 int length = strlen(result);
379 if (length > 1 && result[length - 1] == '/') { 411 if ((length > 1) && (result[length - 1] == '/')) {
380 result[length - 1] = '\0'; 412 result[length - 1] = '\0';
381 } 413 }
382 return result; 414 return path.AsScopedString();
383 } 415 }
384 416
385 417
386 char* Directory::CreateTemp(const char* prefix) { 418 const char* Directory::CreateTemp(const char* prefix) {
387 // Returns a new, unused directory name, adding characters to the end 419 // Returns a new, unused directory name, adding characters to the end
388 // of prefix. Creates the directory with the permissions specified 420 // of prefix. Creates the directory with the permissions specified
389 // by the process umask. 421 // by the process umask.
390 // The return value must be freed by the caller. 422 // The return value is Dart_ScopeAllocated.
391 PathBuffer path; 423 PathBuffer path;
392 path.Add(prefix); 424 if (!path.Add(prefix)) {
425 return NULL;
426 }
393 if (!path.Add("XXXXXX")) { 427 if (!path.Add("XXXXXX")) {
394 // Pattern has overflowed. 428 // Pattern has overflowed.
395 return NULL; 429 return NULL;
396 } 430 }
397 char* result; 431 char* result;
398 do { 432 do {
399 result = mkdtemp(path.AsString()); 433 result = mkdtemp(path.AsString());
400 } while (result == NULL && errno == EINTR); 434 } while ((result == NULL) && (errno == EINTR));
401 if (result == NULL) { 435 if (result == NULL) {
402 return NULL; 436 return NULL;
403 } 437 }
404 return strdup(result); 438 return path.AsScopedString();
405 } 439 }
406 440
407 441
408 bool Directory::Delete(const char* dir_name, bool recursive) { 442 bool Directory::Delete(const char* dir_name, bool recursive) {
409 if (!recursive) { 443 if (!recursive) {
410 if (File::GetType(dir_name, false) == File::kIsLink && 444 if ((File::GetType(dir_name, false) == File::kIsLink) &&
411 File::GetType(dir_name, true) == File::kIsDirectory) { 445 (File::GetType(dir_name, true) == File::kIsDirectory)) {
412 return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0); 446 return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0);
413 } 447 }
414 return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0); 448 return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0);
415 } else { 449 } else {
416 PathBuffer path; 450 PathBuffer path;
417 if (!path.Add(dir_name)) { 451 if (!path.Add(dir_name)) {
418 return false; 452 return false;
419 } 453 }
420 return DeleteRecursively(&path); 454 return DeleteRecursively(&path);
421 } 455 }
422 } 456 }
423 457
424 458
425 bool Directory::Rename(const char* path, const char* new_path) { 459 bool Directory::Rename(const char* path, const char* new_path) {
426 ExistsResult exists = Exists(path); 460 ExistsResult exists = Exists(path);
427 if (exists != EXISTS) return false; 461 if (exists != EXISTS) {
462 return false;
463 }
428 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0); 464 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
429 } 465 }
430 466
431 } // namespace bin 467 } // namespace bin
432 } // namespace dart 468 } // namespace dart
433 469
434 #endif // defined(TARGET_OS_MACOS) 470 #endif // defined(TARGET_OS_MACOS)
OLDNEW
« no previous file with comments | « runtime/bin/directory_linux.cc ('k') | runtime/bin/directory_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698