| 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_LINUX) | 6 #if defined(TARGET_OS_LINUX) |
| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 105 |
| 106 bool File::Flush() { | 106 bool File::Flush() { |
| 107 ASSERT(handle_->fd() >= 0); | 107 ASSERT(handle_->fd() >= 0); |
| 108 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; | 108 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 int64_t File::Length() { | 112 int64_t File::Length() { |
| 113 ASSERT(handle_->fd() >= 0); | 113 ASSERT(handle_->fd() >= 0); |
| 114 struct stat64 st; | 114 struct stat64 st; |
| 115 if (NO_RETRY_EXPECTED(fstat64(handle_->fd(), &st)) == 0) { | 115 if (TEMP_FAILURE_RETRY(fstat64(handle_->fd(), &st)) == 0) { |
| 116 return st.st_size; | 116 return st.st_size; |
| 117 } | 117 } |
| 118 return -1; | 118 return -1; |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 File* File::Open(const char* name, FileOpenMode mode) { | 122 File* File::Open(const char* name, FileOpenMode mode) { |
| 123 // Report errors for non-regular files. | 123 // Report errors for non-regular files. |
| 124 struct stat64 st; | 124 struct stat64 st; |
| 125 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 125 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { |
| 126 // Only accept regular files and character devices. | 126 // Only accept regular files and character devices. |
| 127 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { | 127 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { |
| 128 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; | 128 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; |
| 129 return NULL; | 129 return NULL; |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 int flags = O_RDONLY; | 132 int flags = O_RDONLY; |
| 133 if ((mode & kWrite) != 0) { | 133 if ((mode & kWrite) != 0) { |
| 134 flags = (O_RDWR | O_CREAT); | 134 flags = (O_RDWR | O_CREAT); |
| 135 } | 135 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 152 | 152 |
| 153 | 153 |
| 154 File* File::OpenStdio(int fd) { | 154 File* File::OpenStdio(int fd) { |
| 155 if (fd < 0 || 2 < fd) return NULL; | 155 if (fd < 0 || 2 < fd) return NULL; |
| 156 return new File(new FileHandle(fd)); | 156 return new File(new FileHandle(fd)); |
| 157 } | 157 } |
| 158 | 158 |
| 159 | 159 |
| 160 bool File::Exists(const char* name) { | 160 bool File::Exists(const char* name) { |
| 161 struct stat64 st; | 161 struct stat64 st; |
| 162 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 162 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { |
| 163 return S_ISREG(st.st_mode); | 163 return S_ISREG(st.st_mode); |
| 164 } else { | 164 } else { |
| 165 return false; | 165 return false; |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 bool File::Create(const char* name) { | 170 bool File::Create(const char* name) { |
| 171 int fd = TEMP_FAILURE_RETRY( | 171 int fd = TEMP_FAILURE_RETRY( |
| 172 open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); | 172 open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 errno = EINVAL; | 228 errno = EINVAL; |
| 229 } | 229 } |
| 230 return false; | 230 return false; |
| 231 } | 231 } |
| 232 | 232 |
| 233 | 233 |
| 234 bool File::Copy(const char* old_path, const char* new_path) { | 234 bool File::Copy(const char* old_path, const char* new_path) { |
| 235 File::Type type = File::GetType(old_path, true); | 235 File::Type type = File::GetType(old_path, true); |
| 236 if (type == kIsFile) { | 236 if (type == kIsFile) { |
| 237 struct stat64 st; | 237 struct stat64 st; |
| 238 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) { | 238 if (TEMP_FAILURE_RETRY(stat64(old_path, &st)) != 0) { |
| 239 return false; | 239 return false; |
| 240 } | 240 } |
| 241 int old_fd = TEMP_FAILURE_RETRY(open64(old_path, O_RDONLY | O_CLOEXEC)); | 241 int old_fd = TEMP_FAILURE_RETRY(open64(old_path, O_RDONLY | O_CLOEXEC)); |
| 242 if (old_fd < 0) { | 242 if (old_fd < 0) { |
| 243 return false; | 243 return false; |
| 244 } | 244 } |
| 245 int new_fd = TEMP_FAILURE_RETRY( | 245 int new_fd = TEMP_FAILURE_RETRY( |
| 246 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); | 246 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); |
| 247 if (new_fd < 0) { | 247 if (new_fd < 0) { |
| 248 VOID_TEMP_FAILURE_RETRY(close(old_fd)); | 248 VOID_TEMP_FAILURE_RETRY(close(old_fd)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 errno = EISDIR; | 283 errno = EISDIR; |
| 284 } else { | 284 } else { |
| 285 errno = ENOENT; | 285 errno = ENOENT; |
| 286 } | 286 } |
| 287 return false; | 287 return false; |
| 288 } | 288 } |
| 289 | 289 |
| 290 | 290 |
| 291 int64_t File::LengthFromPath(const char* name) { | 291 int64_t File::LengthFromPath(const char* name) { |
| 292 struct stat64 st; | 292 struct stat64 st; |
| 293 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 293 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { |
| 294 return st.st_size; | 294 return st.st_size; |
| 295 } | 295 } |
| 296 return -1; | 296 return -1; |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| 300 static int64_t TimespecToMilliseconds(const struct timespec& t) { | 300 static int64_t TimespecToMilliseconds(const struct timespec& t) { |
| 301 return static_cast<int64_t>(t.tv_sec) * 1000L + | 301 return static_cast<int64_t>(t.tv_sec) * 1000L + |
| 302 static_cast<int64_t>(t.tv_nsec) / 1000000L; | 302 static_cast<int64_t>(t.tv_nsec) / 1000000L; |
| 303 } | 303 } |
| 304 | 304 |
| 305 | 305 |
| 306 void File::Stat(const char* name, int64_t* data) { | 306 void File::Stat(const char* name, int64_t* data) { |
| 307 struct stat64 st; | 307 struct stat64 st; |
| 308 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 308 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { |
| 309 if (S_ISREG(st.st_mode)) { | 309 if (S_ISREG(st.st_mode)) { |
| 310 data[kType] = kIsFile; | 310 data[kType] = kIsFile; |
| 311 } else if (S_ISDIR(st.st_mode)) { | 311 } else if (S_ISDIR(st.st_mode)) { |
| 312 data[kType] = kIsDirectory; | 312 data[kType] = kIsDirectory; |
| 313 } else if (S_ISLNK(st.st_mode)) { | 313 } else if (S_ISLNK(st.st_mode)) { |
| 314 data[kType] = kIsLink; | 314 data[kType] = kIsLink; |
| 315 } else { | 315 } else { |
| 316 data[kType] = kDoesNotExist; | 316 data[kType] = kDoesNotExist; |
| 317 } | 317 } |
| 318 data[kCreatedTime] = TimespecToMilliseconds(st.st_ctim); | 318 data[kCreatedTime] = TimespecToMilliseconds(st.st_ctim); |
| 319 data[kModifiedTime] = TimespecToMilliseconds(st.st_mtim); | 319 data[kModifiedTime] = TimespecToMilliseconds(st.st_mtim); |
| 320 data[kAccessedTime] = TimespecToMilliseconds(st.st_atim); | 320 data[kAccessedTime] = TimespecToMilliseconds(st.st_atim); |
| 321 data[kMode] = st.st_mode; | 321 data[kMode] = st.st_mode; |
| 322 data[kSize] = st.st_size; | 322 data[kSize] = st.st_size; |
| 323 } else { | 323 } else { |
| 324 data[kType] = kDoesNotExist; | 324 data[kType] = kDoesNotExist; |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 | 328 |
| 329 time_t File::LastModified(const char* name) { | 329 time_t File::LastModified(const char* name) { |
| 330 struct stat64 st; | 330 struct stat64 st; |
| 331 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 331 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { |
| 332 return st.st_mtime; | 332 return st.st_mtime; |
| 333 } | 333 } |
| 334 return -1; | 334 return -1; |
| 335 } | 335 } |
| 336 | 336 |
| 337 | 337 |
| 338 char* File::LinkTarget(const char* pathname) { | 338 char* File::LinkTarget(const char* pathname) { |
| 339 struct stat64 link_stats; | 339 struct stat64 link_stats; |
| 340 if (NO_RETRY_EXPECTED(lstat64(pathname, &link_stats)) != 0) return NULL; | 340 if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) return NULL; |
| 341 if (!S_ISLNK(link_stats.st_mode)) { | 341 if (!S_ISLNK(link_stats.st_mode)) { |
| 342 errno = ENOENT; | 342 errno = ENOENT; |
| 343 return NULL; | 343 return NULL; |
| 344 } | 344 } |
| 345 size_t target_size = link_stats.st_size; | 345 size_t target_size = link_stats.st_size; |
| 346 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1)); | 346 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1)); |
| 347 size_t read_size = NO_RETRY_EXPECTED( | 347 size_t read_size = NO_RETRY_EXPECTED( |
| 348 readlink(pathname, target_name, target_size + 1)); | 348 readlink(pathname, target_name, target_size + 1)); |
| 349 if (read_size != target_size) { | 349 if (read_size != target_size) { |
| 350 free(target_name); | 350 free(target_name); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 378 | 378 |
| 379 | 379 |
| 380 const char* File::StringEscapedPathSeparator() { | 380 const char* File::StringEscapedPathSeparator() { |
| 381 return "/"; | 381 return "/"; |
| 382 } | 382 } |
| 383 | 383 |
| 384 | 384 |
| 385 File::StdioHandleType File::GetStdioHandleType(int fd) { | 385 File::StdioHandleType File::GetStdioHandleType(int fd) { |
| 386 ASSERT(0 <= fd && fd <= 2); | 386 ASSERT(0 <= fd && fd <= 2); |
| 387 struct stat64 buf; | 387 struct stat64 buf; |
| 388 int result = NO_RETRY_EXPECTED(fstat64(fd, &buf)); | 388 int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf)); |
| 389 if (result == -1) { | 389 if (result == -1) { |
| 390 const int kBufferSize = 1024; | 390 const int kBufferSize = 1024; |
| 391 char error_buf[kBufferSize]; | 391 char error_buf[kBufferSize]; |
| 392 FATAL2("Failed stat on file descriptor %d: %s", fd, | 392 FATAL2("Failed stat on file descriptor %d: %s", fd, |
| 393 strerror_r(errno, error_buf, kBufferSize)); | 393 strerror_r(errno, error_buf, kBufferSize)); |
| 394 } | 394 } |
| 395 if (S_ISCHR(buf.st_mode)) return kTerminal; | 395 if (S_ISCHR(buf.st_mode)) return kTerminal; |
| 396 if (S_ISFIFO(buf.st_mode)) return kPipe; | 396 if (S_ISFIFO(buf.st_mode)) return kPipe; |
| 397 if (S_ISSOCK(buf.st_mode)) return kSocket; | 397 if (S_ISSOCK(buf.st_mode)) return kSocket; |
| 398 if (S_ISREG(buf.st_mode)) return kFile; | 398 if (S_ISREG(buf.st_mode)) return kFile; |
| 399 return kOther; | 399 return kOther; |
| 400 } | 400 } |
| 401 | 401 |
| 402 | 402 |
| 403 File::Type File::GetType(const char* pathname, bool follow_links) { | 403 File::Type File::GetType(const char* pathname, bool follow_links) { |
| 404 struct stat64 entry_info; | 404 struct stat64 entry_info; |
| 405 int stat_success; | 405 int stat_success; |
| 406 if (follow_links) { | 406 if (follow_links) { |
| 407 stat_success = NO_RETRY_EXPECTED(stat64(pathname, &entry_info)); | 407 stat_success = TEMP_FAILURE_RETRY(stat64(pathname, &entry_info)); |
| 408 } else { | 408 } else { |
| 409 stat_success = NO_RETRY_EXPECTED(lstat64(pathname, &entry_info)); | 409 stat_success = TEMP_FAILURE_RETRY(lstat64(pathname, &entry_info)); |
| 410 } | 410 } |
| 411 if (stat_success == -1) return File::kDoesNotExist; | 411 if (stat_success == -1) return File::kDoesNotExist; |
| 412 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; | 412 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; |
| 413 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; | 413 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; |
| 414 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; | 414 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; |
| 415 return File::kDoesNotExist; | 415 return File::kDoesNotExist; |
| 416 } | 416 } |
| 417 | 417 |
| 418 | 418 |
| 419 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 419 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
| 420 struct stat64 file_1_info; | 420 struct stat64 file_1_info; |
| 421 struct stat64 file_2_info; | 421 struct stat64 file_2_info; |
| 422 if (NO_RETRY_EXPECTED(lstat64(file_1, &file_1_info)) == -1 || | 422 if (TEMP_FAILURE_RETRY(lstat64(file_1, &file_1_info)) == -1 || |
| 423 NO_RETRY_EXPECTED(lstat64(file_2, &file_2_info)) == -1) { | 423 TEMP_FAILURE_RETRY(lstat64(file_2, &file_2_info)) == -1) { |
| 424 return File::kError; | 424 return File::kError; |
| 425 } | 425 } |
| 426 return (file_1_info.st_ino == file_2_info.st_ino && | 426 return (file_1_info.st_ino == file_2_info.st_ino && |
| 427 file_1_info.st_dev == file_2_info.st_dev) ? | 427 file_1_info.st_dev == file_2_info.st_dev) ? |
| 428 File::kIdentical : | 428 File::kIdentical : |
| 429 File::kDifferent; | 429 File::kDifferent; |
| 430 } | 430 } |
| 431 | 431 |
| 432 } // namespace bin | 432 } // namespace bin |
| 433 } // namespace dart | 433 } // namespace dart |
| 434 | 434 |
| 435 #endif // defined(TARGET_OS_LINUX) | 435 #endif // defined(TARGET_OS_LINUX) |
| OLD | NEW |