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 "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/file.h" | 8 #include "bin/file.h" |
9 | 9 |
10 #include <copyfile.h> // NOLINT | 10 #include <copyfile.h> // NOLINT |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 return is_file; | 261 return is_file; |
262 } | 262 } |
263 | 263 |
264 | 264 |
265 bool File::CreateLink(const char* name, const char* target) { | 265 bool File::CreateLink(const char* name, const char* target) { |
266 int status = NO_RETRY_EXPECTED(symlink(target, name)); | 266 int status = NO_RETRY_EXPECTED(symlink(target, name)); |
267 return (status == 0); | 267 return (status == 0); |
268 } | 268 } |
269 | 269 |
270 | 270 |
271 bool File::Delete(const char* name) { | 271 File::Type File::GetType(const char* pathname, bool follow_links) { |
272 File::Type type = File::GetType(name, true); | 272 struct stat entry_info; |
273 if (type == kIsFile) { | 273 int stat_success; |
274 return NO_RETRY_EXPECTED(unlink(name)) == 0; | 274 if (follow_links) { |
275 } else if (type == kIsDirectory) { | 275 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); |
276 errno = EISDIR; | |
277 } else { | 276 } else { |
278 errno = ENOENT; | 277 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); |
| 278 } |
| 279 if (stat_success == -1) { |
| 280 return File::kDoesNotExist; |
| 281 } |
| 282 if (S_ISDIR(entry_info.st_mode)) { |
| 283 return File::kIsDirectory; |
| 284 } |
| 285 if (S_ISREG(entry_info.st_mode)) { |
| 286 return File::kIsFile; |
| 287 } |
| 288 if (S_ISLNK(entry_info.st_mode)) { |
| 289 return File::kIsLink; |
| 290 } |
| 291 return File::kDoesNotExist; |
| 292 } |
| 293 |
| 294 |
| 295 static bool CheckTypeAndSetErrno(const char* name, |
| 296 File::Type expected, |
| 297 bool follow_links) { |
| 298 File::Type actual = File::GetType(name, follow_links); |
| 299 if (actual == expected) { |
| 300 return true; |
| 301 } |
| 302 switch (actual) { |
| 303 case File::kIsDirectory: |
| 304 errno = EISDIR; |
| 305 break; |
| 306 case File::kDoesNotExist: |
| 307 errno = ENOENT; |
| 308 break; |
| 309 default: |
| 310 errno = EINVAL; |
| 311 break; |
279 } | 312 } |
280 return false; | 313 return false; |
281 } | 314 } |
282 | 315 |
283 | 316 |
| 317 bool File::Delete(const char* name) { |
| 318 return CheckTypeAndSetErrno(name, kIsFile, true) && |
| 319 (NO_RETRY_EXPECTED(unlink(name)) == 0); |
| 320 } |
| 321 |
| 322 |
284 bool File::DeleteLink(const char* name) { | 323 bool File::DeleteLink(const char* name) { |
285 File::Type type = File::GetType(name, false); | 324 return CheckTypeAndSetErrno(name, kIsLink, false) && |
286 if (type == kIsLink) { | 325 (NO_RETRY_EXPECTED(unlink(name)) == 0); |
287 return NO_RETRY_EXPECTED(unlink(name)) == 0; | |
288 } | |
289 errno = EINVAL; | |
290 return false; | |
291 } | 326 } |
292 | 327 |
293 | 328 |
294 bool File::Rename(const char* old_path, const char* new_path) { | 329 bool File::Rename(const char* old_path, const char* new_path) { |
295 File::Type type = File::GetType(old_path, true); | 330 return CheckTypeAndSetErrno(old_path, kIsFile, true) && |
296 if (type == kIsFile) { | 331 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); |
297 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0; | |
298 } else if (type == kIsDirectory) { | |
299 errno = EISDIR; | |
300 } else { | |
301 errno = ENOENT; | |
302 } | |
303 return false; | |
304 } | 332 } |
305 | 333 |
306 | 334 |
307 bool File::RenameLink(const char* old_path, const char* new_path) { | 335 bool File::RenameLink(const char* old_path, const char* new_path) { |
308 File::Type type = File::GetType(old_path, false); | 336 return CheckTypeAndSetErrno(old_path, kIsLink, false) && |
309 if (type == kIsLink) { | 337 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); |
310 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0; | |
311 } else if (type == kIsDirectory) { | |
312 errno = EISDIR; | |
313 } else { | |
314 errno = EINVAL; | |
315 } | |
316 return false; | |
317 } | 338 } |
318 | 339 |
319 | 340 |
320 bool File::Copy(const char* old_path, const char* new_path) { | 341 bool File::Copy(const char* old_path, const char* new_path) { |
321 File::Type type = File::GetType(old_path, true); | 342 return CheckTypeAndSetErrno(old_path, kIsFile, true) && |
322 if (type == kIsFile) { | 343 (copyfile(old_path, new_path, NULL, COPYFILE_ALL) == 0); |
323 return copyfile(old_path, new_path, NULL, COPYFILE_ALL) == 0; | |
324 } else if (type == kIsDirectory) { | |
325 errno = EISDIR; | |
326 } else { | |
327 errno = ENOENT; | |
328 } | |
329 return false; | |
330 } | 344 } |
331 | 345 |
332 | 346 |
333 int64_t File::LengthFromPath(const char* name) { | 347 int64_t File::LengthFromPath(const char* name) { |
334 struct stat st; | 348 struct stat st; |
335 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 349 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
336 // Signal an error if it's a directory. | 350 // Signal an error if it's a directory. |
337 if (S_ISDIR(st.st_mode)) { | 351 if (S_ISDIR(st.st_mode)) { |
338 errno = EISDIR; | 352 errno = EISDIR; |
339 return -1; | 353 return -1; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 if (S_ISSOCK(buf.st_mode)) { | 484 if (S_ISSOCK(buf.st_mode)) { |
471 return kSocket; | 485 return kSocket; |
472 } | 486 } |
473 if (S_ISREG(buf.st_mode)) { | 487 if (S_ISREG(buf.st_mode)) { |
474 return kFile; | 488 return kFile; |
475 } | 489 } |
476 return kOther; | 490 return kOther; |
477 } | 491 } |
478 | 492 |
479 | 493 |
480 File::Type File::GetType(const char* pathname, bool follow_links) { | |
481 struct stat entry_info; | |
482 int stat_success; | |
483 if (follow_links) { | |
484 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); | |
485 } else { | |
486 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); | |
487 } | |
488 if (stat_success == -1) { | |
489 return File::kDoesNotExist; | |
490 } | |
491 if (S_ISDIR(entry_info.st_mode)) { | |
492 return File::kIsDirectory; | |
493 } | |
494 if (S_ISREG(entry_info.st_mode)) { | |
495 return File::kIsFile; | |
496 } | |
497 if (S_ISLNK(entry_info.st_mode)) { | |
498 return File::kIsLink; | |
499 } | |
500 return File::kDoesNotExist; | |
501 } | |
502 | |
503 | |
504 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 494 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
505 struct stat file_1_info; | 495 struct stat file_1_info; |
506 struct stat file_2_info; | 496 struct stat file_2_info; |
507 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || | 497 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || |
508 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { | 498 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { |
509 return File::kError; | 499 return File::kError; |
510 } | 500 } |
511 return ((file_1_info.st_ino == file_2_info.st_ino) && | 501 return ((file_1_info.st_ino == file_2_info.st_ino) && |
512 (file_1_info.st_dev == file_2_info.st_dev)) | 502 (file_1_info.st_dev == file_2_info.st_dev)) |
513 ? File::kIdentical | 503 ? File::kIdentical |
514 : File::kDifferent; | 504 : File::kDifferent; |
515 } | 505 } |
516 | 506 |
517 } // namespace bin | 507 } // namespace bin |
518 } // namespace dart | 508 } // namespace dart |
519 | 509 |
520 #endif // defined(TARGET_OS_MACOS) | 510 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |