Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: runtime/bin/file_linux.cc

Issue 600273004: Remove the assumption that stat64 and lstat64 cannot return EINTR on Linux (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/directory_linux.cc ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/bin/directory_linux.cc ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698