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 |