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(HOST_OS_MACOS) | 6 #if defined(HOST_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/dartutils.h" |
18 #include "bin/file.h" | 18 #include "bin/file.h" |
| 19 #include "bin/namespace.h" |
19 #include "bin/platform.h" | 20 #include "bin/platform.h" |
20 #include "platform/signal_blocker.h" | 21 #include "platform/signal_blocker.h" |
21 | 22 |
22 namespace dart { | 23 namespace dart { |
23 namespace bin { | 24 namespace bin { |
24 | 25 |
25 PathBuffer::PathBuffer() : length_(0) { | 26 PathBuffer::PathBuffer() : length_(0) { |
26 data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT | 27 data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT |
27 } | 28 } |
28 | 29 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 path->Reset(path_length); | 322 path->Reset(path_length); |
322 } | 323 } |
323 // Only happens if an error. | 324 // Only happens if an error. |
324 ASSERT(errno != 0); | 325 ASSERT(errno != 0); |
325 int err = errno; | 326 int err = errno; |
326 VOID_NO_RETRY_EXPECTED(closedir(dir_pointer)); | 327 VOID_NO_RETRY_EXPECTED(closedir(dir_pointer)); |
327 errno = err; | 328 errno = err; |
328 return false; | 329 return false; |
329 } | 330 } |
330 | 331 |
331 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 332 Directory::ExistsResult Directory::Exists(Namespace* namespc, const char* dir_na
me) { |
332 struct stat entry_info; | 333 struct stat entry_info; |
333 int success = NO_RETRY_EXPECTED(stat(dir_name, &entry_info)); | 334 int success = NO_RETRY_EXPECTED(stat(dir_name, &entry_info)); |
334 if (success == 0) { | 335 if (success == 0) { |
335 if (S_ISDIR(entry_info.st_mode)) { | 336 if (S_ISDIR(entry_info.st_mode)) { |
336 return EXISTS; | 337 return EXISTS; |
337 } else { | 338 } else { |
338 // An OSError may be constructed based on the return value of this | 339 // An OSError may be constructed based on the return value of this |
339 // function, so set errno to something that makes sense. | 340 // function, so set errno to something that makes sense. |
340 errno = ENOTDIR; | 341 errno = ENOTDIR; |
341 return DOES_NOT_EXIST; | 342 return DOES_NOT_EXIST; |
342 } | 343 } |
343 } else { | 344 } else { |
344 if ((errno == EACCES) || (errno == EBADF) || (errno == EFAULT) || | 345 if ((errno == EACCES) || (errno == EBADF) || (errno == EFAULT) || |
345 (errno == ENOMEM) || (errno == EOVERFLOW)) { | 346 (errno == ENOMEM) || (errno == EOVERFLOW)) { |
346 // Search permissions denied for one of the directories in the | 347 // Search permissions denied for one of the directories in the |
347 // path or a low level error occured. We do not know if the | 348 // path or a low level error occured. We do not know if the |
348 // directory exists. | 349 // directory exists. |
349 return UNKNOWN; | 350 return UNKNOWN; |
350 } | 351 } |
351 ASSERT((errno == ELOOP) || (errno == ENAMETOOLONG) || (errno == ENOENT) || | 352 ASSERT((errno == ELOOP) || (errno == ENAMETOOLONG) || (errno == ENOENT) || |
352 (errno == ENOTDIR)); | 353 (errno == ENOTDIR)); |
353 return DOES_NOT_EXIST; | 354 return DOES_NOT_EXIST; |
354 } | 355 } |
355 } | 356 } |
356 | 357 |
357 char* Directory::CurrentNoScope() { | 358 char* Directory::CurrentNoScope() { |
358 return getcwd(NULL, 0); | 359 return getcwd(NULL, 0); |
359 } | 360 } |
360 | 361 |
361 const char* Directory::Current() { | 362 bool Directory::Create(Namespace* namespc, const char* dir_name) { |
362 char buffer[PATH_MAX]; | |
363 if (getcwd(buffer, PATH_MAX) == NULL) { | |
364 return NULL; | |
365 } | |
366 return DartUtils::ScopedCopyCString(buffer); | |
367 } | |
368 | |
369 bool Directory::SetCurrent(const char* path) { | |
370 int result = NO_RETRY_EXPECTED(chdir(path)); | |
371 return (result == 0); | |
372 } | |
373 | |
374 bool Directory::Create(const char* dir_name) { | |
375 // Create the directory with the permissions specified by the | 363 // Create the directory with the permissions specified by the |
376 // process umask. | 364 // process umask. |
377 int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777)); | 365 int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777)); |
378 // If the directory already exists, treat it as a success. | 366 // If the directory already exists, treat it as a success. |
379 if ((result == -1) && (errno == EEXIST)) { | 367 if ((result == -1) && (errno == EEXIST)) { |
380 return (Exists(dir_name) == EXISTS); | 368 return (Exists(namespc, dir_name) == EXISTS); |
381 } | 369 } |
382 return (result == 0); | 370 return (result == 0); |
383 } | 371 } |
384 | 372 |
385 const char* Directory::SystemTemp() { | 373 const char* Directory::SystemTemp(Namespace* namespc) { |
386 PathBuffer path; | 374 PathBuffer path; |
387 const char* temp_dir = getenv("TMPDIR"); | 375 const char* temp_dir = getenv("TMPDIR"); |
388 if (temp_dir == NULL) { | 376 if (temp_dir == NULL) { |
389 temp_dir = getenv("TMP"); | 377 temp_dir = getenv("TMP"); |
390 } | 378 } |
391 if (temp_dir == NULL) { | 379 if (temp_dir == NULL) { |
392 temp_dir = "/tmp"; | 380 temp_dir = "/tmp"; |
393 } | 381 } |
394 if (!path.Add(temp_dir)) { | 382 if (!path.Add(temp_dir)) { |
395 return NULL; | 383 return NULL; |
396 } | 384 } |
397 // Remove any trailing slash. | 385 // Remove any trailing slash. |
398 char* result = path.AsString(); | 386 char* result = path.AsString(); |
399 int length = strlen(result); | 387 int length = strlen(result); |
400 if ((length > 1) && (result[length - 1] == '/')) { | 388 if ((length > 1) && (result[length - 1] == '/')) { |
401 result[length - 1] = '\0'; | 389 result[length - 1] = '\0'; |
402 } | 390 } |
403 return path.AsScopedString(); | 391 return path.AsScopedString(); |
404 } | 392 } |
405 | 393 |
406 const char* Directory::CreateTemp(const char* prefix) { | 394 const char* Directory::CreateTemp(Namespace* namespc, const char* prefix) { |
407 // Returns a new, unused directory name, adding characters to the end | 395 // Returns a new, unused directory name, adding characters to the end |
408 // of prefix. Creates the directory with the permissions specified | 396 // of prefix. Creates the directory with the permissions specified |
409 // by the process umask. | 397 // by the process umask. |
410 // The return value is Dart_ScopeAllocated. | 398 // The return value is Dart_ScopeAllocated. |
411 PathBuffer path; | 399 PathBuffer path; |
412 if (!path.Add(prefix)) { | 400 if (!path.Add(prefix)) { |
413 return NULL; | 401 return NULL; |
414 } | 402 } |
415 if (!path.Add("XXXXXX")) { | 403 if (!path.Add("XXXXXX")) { |
416 // Pattern has overflowed. | 404 // Pattern has overflowed. |
417 return NULL; | 405 return NULL; |
418 } | 406 } |
419 char* result; | 407 char* result; |
420 do { | 408 do { |
421 result = mkdtemp(path.AsString()); | 409 result = mkdtemp(path.AsString()); |
422 } while ((result == NULL) && (errno == EINTR)); | 410 } while ((result == NULL) && (errno == EINTR)); |
423 if (result == NULL) { | 411 if (result == NULL) { |
424 return NULL; | 412 return NULL; |
425 } | 413 } |
426 return path.AsScopedString(); | 414 return path.AsScopedString(); |
427 } | 415 } |
428 | 416 |
429 bool Directory::Delete(const char* dir_name, bool recursive) { | 417 bool Directory::Delete(Namespace* namespc, const char* dir_name, bool recursive)
{ |
430 if (!recursive) { | 418 if (!recursive) { |
431 if ((File::GetType(dir_name, false) == File::kIsLink) && | 419 if ((File::GetType(namespc, dir_name, false) == File::kIsLink) && |
432 (File::GetType(dir_name, true) == File::kIsDirectory)) { | 420 (File::GetType(namespc, dir_name, true) == File::kIsDirectory)) { |
433 return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0); | 421 return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0); |
434 } | 422 } |
435 return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0); | 423 return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0); |
436 } else { | 424 } else { |
437 PathBuffer path; | 425 PathBuffer path; |
438 if (!path.Add(dir_name)) { | 426 if (!path.Add(dir_name)) { |
439 return false; | 427 return false; |
440 } | 428 } |
441 return DeleteRecursively(&path); | 429 return DeleteRecursively(&path); |
442 } | 430 } |
443 } | 431 } |
444 | 432 |
445 bool Directory::Rename(const char* path, const char* new_path) { | 433 bool Directory::Rename(Namespace* namespc, const char* path, const char* new_pat
h) { |
446 ExistsResult exists = Exists(path); | 434 ExistsResult exists = Exists(namespc, path); |
447 if (exists != EXISTS) { | 435 if (exists != EXISTS) { |
448 return false; | 436 return false; |
449 } | 437 } |
450 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0); | 438 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0); |
451 } | 439 } |
452 | 440 |
453 } // namespace bin | 441 } // namespace bin |
454 } // namespace dart | 442 } // namespace dart |
455 | 443 |
456 #endif // defined(HOST_OS_MACOS) | 444 #endif // defined(HOST_OS_MACOS) |
OLD | NEW |