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 <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 | 108 |
109 bool File::Flush() { | 109 bool File::Flush() { |
110 ASSERT(handle_->fd() >= 0); | 110 ASSERT(handle_->fd() >= 0); |
111 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; | 111 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { | 115 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { |
116 ASSERT(handle_->fd() >= 0); | 116 ASSERT(handle_->fd() >= 0); |
117 ASSERT(end == -1 || end > start); | 117 ASSERT((end == -1) || (end > start)); |
118 struct flock fl; | 118 struct flock fl; |
119 switch (lock) { | 119 switch (lock) { |
120 case File::kLockUnlock: | 120 case File::kLockUnlock: |
121 fl.l_type = F_UNLCK; | 121 fl.l_type = F_UNLCK; |
122 break; | 122 break; |
123 case File::kLockShared: | 123 case File::kLockShared: |
124 fl.l_type = F_RDLCK; | 124 fl.l_type = F_RDLCK; |
125 break; | 125 break; |
126 case File::kLockExclusive: | 126 case File::kLockExclusive: |
127 fl.l_type = F_WRLCK; | 127 fl.l_type = F_WRLCK; |
(...skipping 13 matching lines...) Expand all Loading... |
141 int64_t File::Length() { | 141 int64_t File::Length() { |
142 ASSERT(handle_->fd() >= 0); | 142 ASSERT(handle_->fd() >= 0); |
143 struct stat st; | 143 struct stat st; |
144 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) { | 144 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) { |
145 return st.st_size; | 145 return st.st_size; |
146 } | 146 } |
147 return -1; | 147 return -1; |
148 } | 148 } |
149 | 149 |
150 | 150 |
151 File* File::Open(const char* name, FileOpenMode mode) { | 151 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { |
| 152 UNREACHABLE(); |
| 153 return NULL; |
| 154 } |
| 155 |
| 156 |
| 157 File* File::ScopedOpen(const char* name, FileOpenMode mode) { |
152 // Report errors for non-regular files. | 158 // Report errors for non-regular files. |
153 struct stat st; | 159 struct stat st; |
154 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 160 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
155 // Only accept regular files and character devices. | 161 // Only accept regular files and character devices. |
156 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { | 162 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { |
157 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; | 163 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; |
158 return NULL; | 164 return NULL; |
159 } | 165 } |
160 } | 166 } |
161 int flags = O_RDONLY; | 167 int flags = O_RDONLY; |
(...skipping 17 matching lines...) Expand all Loading... |
179 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { | 185 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { |
180 int64_t position = lseek(fd, 0, SEEK_END); | 186 int64_t position = lseek(fd, 0, SEEK_END); |
181 if (position < 0) { | 187 if (position < 0) { |
182 return NULL; | 188 return NULL; |
183 } | 189 } |
184 } | 190 } |
185 return new File(new FileHandle(fd)); | 191 return new File(new FileHandle(fd)); |
186 } | 192 } |
187 | 193 |
188 | 194 |
| 195 File* File::Open(const char* path, FileOpenMode mode) { |
| 196 // ScopedOpen doesn't actually need a scope. |
| 197 return ScopedOpen(path, mode); |
| 198 } |
| 199 |
| 200 |
189 File* File::OpenStdio(int fd) { | 201 File* File::OpenStdio(int fd) { |
190 if (fd < 0 || 2 < fd) return NULL; | 202 if ((fd < 0) || (2 < fd)) { |
| 203 return NULL; |
| 204 } |
191 return new File(new FileHandle(fd)); | 205 return new File(new FileHandle(fd)); |
192 } | 206 } |
193 | 207 |
194 | 208 |
195 bool File::Exists(const char* name) { | 209 bool File::Exists(const char* name) { |
196 struct stat st; | 210 struct stat st; |
197 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 211 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
198 return S_ISREG(st.st_mode); | 212 return S_ISREG(st.st_mode); |
199 } else { | 213 } else { |
200 return false; | 214 return false; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 | 336 |
323 time_t File::LastModified(const char* name) { | 337 time_t File::LastModified(const char* name) { |
324 struct stat st; | 338 struct stat st; |
325 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 339 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
326 return st.st_mtime; | 340 return st.st_mtime; |
327 } | 341 } |
328 return -1; | 342 return -1; |
329 } | 343 } |
330 | 344 |
331 | 345 |
332 char* File::LinkTarget(const char* pathname) { | 346 const char* File::LinkTarget(const char* pathname) { |
333 struct stat link_stats; | 347 struct stat link_stats; |
334 if (lstat(pathname, &link_stats) != 0) return NULL; | 348 if (lstat(pathname, &link_stats) != 0) { |
| 349 return NULL; |
| 350 } |
335 if (!S_ISLNK(link_stats.st_mode)) { | 351 if (!S_ISLNK(link_stats.st_mode)) { |
336 errno = ENOENT; | 352 errno = ENOENT; |
337 return NULL; | 353 return NULL; |
338 } | 354 } |
339 // Don't rely on the link_stats.st_size for the size of the link | 355 // Don't rely on the link_stats.st_size for the size of the link |
340 // target. The link might have changed before the readlink call. | 356 // target. The link might have changed before the readlink call. |
341 const int kBufferSize = 1024; | 357 const int kBufferSize = 1024; |
342 char target[kBufferSize]; | 358 char target[kBufferSize]; |
343 size_t target_size = TEMP_FAILURE_RETRY( | 359 size_t target_size = TEMP_FAILURE_RETRY( |
344 readlink(pathname, target, kBufferSize)); | 360 readlink(pathname, target, kBufferSize)); |
345 if (target_size <= 0) { | 361 if (target_size <= 0) { |
346 return NULL; | 362 return NULL; |
347 } | 363 } |
348 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1)); | 364 char* target_name = DartUtils::ScopedCString(target_size + 1); |
349 if (target_name == NULL) { | 365 ASSERT(target_name != NULL); |
350 return NULL; | |
351 } | |
352 memmove(target_name, target, target_size); | 366 memmove(target_name, target, target_size); |
353 target_name[target_size] = '\0'; | 367 target_name[target_size] = '\0'; |
354 return target_name; | 368 return target_name; |
355 } | 369 } |
356 | 370 |
357 | 371 |
358 bool File::IsAbsolutePath(const char* pathname) { | 372 bool File::IsAbsolutePath(const char* pathname) { |
359 return (pathname != NULL && pathname[0] == '/'); | 373 return (pathname != NULL && pathname[0] == '/'); |
360 } | 374 } |
361 | 375 |
362 | 376 |
363 char* File::GetCanonicalPath(const char* pathname) { | 377 const char* File::GetCanonicalPath(const char* pathname) { |
364 char* abs_path = NULL; | 378 char* abs_path = NULL; |
365 if (pathname != NULL) { | 379 if (pathname != NULL) { |
366 // On some older MacOs versions the default behaviour of realpath allocating | 380 // On some older MacOs versions the default behaviour of realpath allocating |
367 // space for the resolved_path when a NULL is passed in does not seem to | 381 // space for the resolved_path when a NULL is passed in does not seem to |
368 // work, so we explicitly allocate space. The caller is responsible for | 382 // work, so we explicitly allocate space. |
369 // freeing this space as in a regular realpath call. | 383 char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1); |
370 char* resolved_path = reinterpret_cast<char*>(malloc(PATH_MAX + 1)); | |
371 ASSERT(resolved_path != NULL); | 384 ASSERT(resolved_path != NULL); |
372 do { | 385 do { |
373 abs_path = realpath(pathname, NULL); | 386 abs_path = realpath(pathname, resolved_path); |
374 } while (abs_path == NULL && errno == EINTR); | 387 } while ((abs_path == NULL) && (errno == EINTR)); |
375 ASSERT(abs_path == NULL || IsAbsolutePath(abs_path)); | 388 ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path)); |
| 389 ASSERT((abs_path == NULL) || (abs_path == resolved_path)); |
376 } | 390 } |
377 return abs_path; | 391 return abs_path; |
378 } | 392 } |
379 | 393 |
380 | 394 |
381 const char* File::PathSeparator() { | 395 const char* File::PathSeparator() { |
382 return "/"; | 396 return "/"; |
383 } | 397 } |
384 | 398 |
385 | 399 |
386 const char* File::StringEscapedPathSeparator() { | 400 const char* File::StringEscapedPathSeparator() { |
387 return "/"; | 401 return "/"; |
388 } | 402 } |
389 | 403 |
390 | 404 |
391 File::StdioHandleType File::GetStdioHandleType(int fd) { | 405 File::StdioHandleType File::GetStdioHandleType(int fd) { |
392 ASSERT(0 <= fd && fd <= 2); | 406 ASSERT((0 <= fd) && (fd <= 2)); |
393 struct stat buf; | 407 struct stat buf; |
394 int result = fstat(fd, &buf); | 408 int result = fstat(fd, &buf); |
395 if (result == -1) { | 409 if (result == -1) { |
396 const int kBufferSize = 1024; | 410 const int kBufferSize = 1024; |
397 char error_message[kBufferSize]; | 411 char error_message[kBufferSize]; |
398 Utils::StrError(errno, error_message, kBufferSize); | 412 Utils::StrError(errno, error_message, kBufferSize); |
399 FATAL2("Failed stat on file descriptor %d: %s", fd, error_message); | 413 FATAL2("Failed stat on file descriptor %d: %s", fd, error_message); |
400 } | 414 } |
401 if (S_ISCHR(buf.st_mode)) return kTerminal; | 415 if (S_ISCHR(buf.st_mode)) { |
402 if (S_ISFIFO(buf.st_mode)) return kPipe; | 416 return kTerminal; |
403 if (S_ISSOCK(buf.st_mode)) return kSocket; | 417 } |
404 if (S_ISREG(buf.st_mode)) return kFile; | 418 if (S_ISFIFO(buf.st_mode)) { |
| 419 return kPipe; |
| 420 } |
| 421 if (S_ISSOCK(buf.st_mode)) { |
| 422 return kSocket; |
| 423 } |
| 424 if (S_ISREG(buf.st_mode)) { |
| 425 return kFile; |
| 426 } |
405 return kOther; | 427 return kOther; |
406 } | 428 } |
407 | 429 |
408 | 430 |
409 File::Type File::GetType(const char* pathname, bool follow_links) { | 431 File::Type File::GetType(const char* pathname, bool follow_links) { |
410 struct stat entry_info; | 432 struct stat entry_info; |
411 int stat_success; | 433 int stat_success; |
412 if (follow_links) { | 434 if (follow_links) { |
413 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); | 435 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); |
414 } else { | 436 } else { |
415 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); | 437 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); |
416 } | 438 } |
417 if (stat_success == -1) return File::kDoesNotExist; | 439 if (stat_success == -1) { |
418 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; | 440 return File::kDoesNotExist; |
419 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; | 441 } |
420 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; | 442 if (S_ISDIR(entry_info.st_mode)) { |
| 443 return File::kIsDirectory; |
| 444 } |
| 445 if (S_ISREG(entry_info.st_mode)) { |
| 446 return File::kIsFile; |
| 447 } |
| 448 if (S_ISLNK(entry_info.st_mode)) { |
| 449 return File::kIsLink; |
| 450 } |
421 return File::kDoesNotExist; | 451 return File::kDoesNotExist; |
422 } | 452 } |
423 | 453 |
424 | 454 |
425 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 455 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
426 struct stat file_1_info; | 456 struct stat file_1_info; |
427 struct stat file_2_info; | 457 struct stat file_2_info; |
428 if (NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1 || | 458 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || |
429 NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1) { | 459 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { |
430 return File::kError; | 460 return File::kError; |
431 } | 461 } |
432 return (file_1_info.st_ino == file_2_info.st_ino && | 462 return ((file_1_info.st_ino == file_2_info.st_ino) && |
433 file_1_info.st_dev == file_2_info.st_dev) ? | 463 (file_1_info.st_dev == file_2_info.st_dev)) ? |
434 File::kIdentical : | 464 File::kIdentical : |
435 File::kDifferent; | 465 File::kDifferent; |
436 } | 466 } |
437 | 467 |
438 } // namespace bin | 468 } // namespace bin |
439 } // namespace dart | 469 } // namespace dart |
440 | 470 |
441 #endif // defined(TARGET_OS_MACOS) | 471 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |