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

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

Issue 2612653003: Standardize errno's from a few dart:io File and Link calls (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « no previous file | runtime/bin/file_fuchsia.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_ANDROID) 6 #if defined(TARGET_OS_ANDROID)
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 return is_file; 258 return is_file;
259 } 259 }
260 260
261 261
262 bool File::CreateLink(const char* name, const char* target) { 262 bool File::CreateLink(const char* name, const char* target) {
263 int status = NO_RETRY_EXPECTED(symlink(target, name)); 263 int status = NO_RETRY_EXPECTED(symlink(target, name));
264 return (status == 0); 264 return (status == 0);
265 } 265 }
266 266
267 267
268 bool File::Delete(const char* name) { 268 File::Type File::GetType(const char* pathname, bool follow_links) {
269 File::Type type = File::GetType(name, true); 269 struct stat entry_info;
270 if (type == kIsFile) { 270 int stat_success;
271 return NO_RETRY_EXPECTED(unlink(name)) == 0; 271 if (follow_links) {
272 } else if (type == kIsDirectory) { 272 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
273 errno = EISDIR;
274 } else { 273 } else {
275 errno = ENOENT; 274 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
275 }
276 if (stat_success == -1) {
277 return File::kDoesNotExist;
278 }
279 if (S_ISDIR(entry_info.st_mode)) {
280 return File::kIsDirectory;
281 }
282 if (S_ISREG(entry_info.st_mode)) {
283 return File::kIsFile;
284 }
285 if (S_ISLNK(entry_info.st_mode)) {
286 return File::kIsLink;
287 }
288 return File::kDoesNotExist;
289 }
290
291
292 static bool CheckTypeAndSetErrno(const char* name,
293 File::Type expected,
294 bool follow_links) {
295 File::Type actual = File::GetType(name, follow_links);
296 if (actual == expected) {
297 return true;
298 }
299 switch (actual) {
300 case File::kIsDirectory:
301 errno = EISDIR;
302 break;
303 case File::kDoesNotExist:
304 errno = ENOENT;
305 break;
306 default:
307 errno = EINVAL;
308 break;
276 } 309 }
277 return false; 310 return false;
278 } 311 }
279 312
280 313
314 bool File::Delete(const char* name) {
315 return CheckTypeAndSetErrno(name, kIsFile, true) &&
316 (NO_RETRY_EXPECTED(unlink(name)) == 0);
317 }
318
319
281 bool File::DeleteLink(const char* name) { 320 bool File::DeleteLink(const char* name) {
282 File::Type type = File::GetType(name, false); 321 return CheckTypeAndSetErrno(name, kIsLink, false) &&
283 if (type == kIsLink) { 322 (NO_RETRY_EXPECTED(unlink(name)) == 0);
284 return NO_RETRY_EXPECTED(unlink(name)) == 0;
285 }
286 errno = EINVAL;
287 return false;
288 } 323 }
289 324
290 325
291 bool File::Rename(const char* old_path, const char* new_path) { 326 bool File::Rename(const char* old_path, const char* new_path) {
292 File::Type type = File::GetType(old_path, true); 327 return CheckTypeAndSetErrno(old_path, kIsFile, true) &&
293 if (type == kIsFile) { 328 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
294 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
295 } else if (type == kIsDirectory) {
296 errno = EISDIR;
297 } else {
298 errno = ENOENT;
299 }
300 return false;
301 } 329 }
302 330
303 331
304 bool File::RenameLink(const char* old_path, const char* new_path) { 332 bool File::RenameLink(const char* old_path, const char* new_path) {
305 File::Type type = File::GetType(old_path, false); 333 return CheckTypeAndSetErrno(old_path, kIsLink, false) &&
306 if (type == kIsLink) { 334 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
307 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
308 } else if (type == kIsDirectory) {
309 errno = EISDIR;
310 } else {
311 errno = EINVAL;
312 }
313 return false;
314 } 335 }
315 336
316 337
317 bool File::Copy(const char* old_path, const char* new_path) { 338 bool File::Copy(const char* old_path, const char* new_path) {
318 File::Type type = File::GetType(old_path, true); 339 if (!CheckTypeAndSetErrno(old_path, kIsFile, true)) {
319 if (type == kIsFile) { 340 return false;
320 struct stat st; 341 }
321 if (NO_RETRY_EXPECTED(stat(old_path, &st)) != 0) { 342 struct stat st;
322 return false; 343 if (NO_RETRY_EXPECTED(stat(old_path, &st)) != 0) {
323 } 344 return false;
324 int old_fd = TEMP_FAILURE_RETRY(open(old_path, O_RDONLY | O_CLOEXEC)); 345 }
325 if (old_fd < 0) { 346 int old_fd = TEMP_FAILURE_RETRY(open(old_path, O_RDONLY | O_CLOEXEC));
326 return false; 347 if (old_fd < 0) {
327 } 348 return false;
328 int new_fd = TEMP_FAILURE_RETRY( 349 }
329 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); 350 int new_fd = TEMP_FAILURE_RETRY(
330 if (new_fd < 0) { 351 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
331 VOID_TEMP_FAILURE_RETRY(close(old_fd)); 352 if (new_fd < 0) {
332 return false; 353 VOID_TEMP_FAILURE_RETRY(close(old_fd));
333 } 354 return false;
334 off_t offset = 0; 355 }
335 int result = 1; 356 off_t offset = 0;
336 while (result > 0) { 357 int result = 1;
337 // Loop to ensure we copy everything, and not only up to 2GB. 358 while (result > 0) {
338 result = NO_RETRY_EXPECTED(sendfile(new_fd, old_fd, &offset, kMaxUint32)); 359 // Loop to ensure we copy everything, and not only up to 2GB.
339 } 360 result = NO_RETRY_EXPECTED(sendfile(new_fd, old_fd, &offset, kMaxUint32));
340 // From sendfile man pages: 361 }
341 // Applications may wish to fall back to read(2)/write(2) in the case 362 // From sendfile man pages:
342 // where sendfile() fails with EINVAL or ENOSYS. 363 // Applications may wish to fall back to read(2)/write(2) in the case
343 if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) { 364 // where sendfile() fails with EINVAL or ENOSYS.
344 const intptr_t kBufferSize = 8 * KB; 365 if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) {
345 uint8_t buffer[kBufferSize]; 366 const intptr_t kBufferSize = 8 * KB;
346 while ((result = TEMP_FAILURE_RETRY(read(old_fd, buffer, kBufferSize))) > 367 uint8_t buffer[kBufferSize];
347 0) { 368 while ((result = TEMP_FAILURE_RETRY(read(old_fd, buffer, kBufferSize))) >
348 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result)); 369 0) {
349 if (wrote != result) { 370 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result));
350 result = -1; 371 if (wrote != result) {
351 break; 372 result = -1;
352 } 373 break;
353 } 374 }
354 } 375 }
355 int e = errno;
356 VOID_TEMP_FAILURE_RETRY(close(old_fd));
357 VOID_TEMP_FAILURE_RETRY(close(new_fd));
358 if (result < 0) {
359 VOID_NO_RETRY_EXPECTED(unlink(new_path));
360 errno = e;
361 return false;
362 }
363 return true;
364 } else if (type == kIsDirectory) {
365 errno = EISDIR;
366 } else {
367 errno = ENOENT;
368 } 376 }
369 return false; 377 int e = errno;
378 VOID_TEMP_FAILURE_RETRY(close(old_fd));
379 VOID_TEMP_FAILURE_RETRY(close(new_fd));
380 if (result < 0) {
381 VOID_NO_RETRY_EXPECTED(unlink(new_path));
382 errno = e;
383 return false;
384 }
385 return true;
370 } 386 }
371 387
372 388
373 int64_t File::LengthFromPath(const char* name) { 389 int64_t File::LengthFromPath(const char* name) {
374 struct stat st; 390 struct stat st;
375 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 391 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
376 // Signal an error if it's a directory. 392 // Signal an error if it's a directory.
377 if (S_ISDIR(st.st_mode)) { 393 if (S_ISDIR(st.st_mode)) {
378 errno = EISDIR; 394 errno = EISDIR;
379 return -1; 395 return -1;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (S_ISSOCK(buf.st_mode)) { 509 if (S_ISSOCK(buf.st_mode)) {
494 return kSocket; 510 return kSocket;
495 } 511 }
496 if (S_ISREG(buf.st_mode)) { 512 if (S_ISREG(buf.st_mode)) {
497 return kFile; 513 return kFile;
498 } 514 }
499 return kOther; 515 return kOther;
500 } 516 }
501 517
502 518
503 File::Type File::GetType(const char* pathname, bool follow_links) {
504 struct stat entry_info;
505 int stat_success;
506 if (follow_links) {
507 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
508 } else {
509 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
510 }
511 if (stat_success == -1) {
512 return File::kDoesNotExist;
513 }
514 if (S_ISDIR(entry_info.st_mode)) {
515 return File::kIsDirectory;
516 }
517 if (S_ISREG(entry_info.st_mode)) {
518 return File::kIsFile;
519 }
520 if (S_ISLNK(entry_info.st_mode)) {
521 return File::kIsLink;
522 }
523 return File::kDoesNotExist;
524 }
525
526
527 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { 519 File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
528 struct stat file_1_info; 520 struct stat file_1_info;
529 struct stat file_2_info; 521 struct stat file_2_info;
530 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || 522 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
531 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { 523 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
532 return File::kError; 524 return File::kError;
533 } 525 }
534 return ((file_1_info.st_ino == file_2_info.st_ino) && 526 return ((file_1_info.st_ino == file_2_info.st_ino) &&
535 (file_1_info.st_dev == file_2_info.st_dev)) 527 (file_1_info.st_dev == file_2_info.st_dev))
536 ? File::kIdentical 528 ? File::kIdentical
537 : File::kDifferent; 529 : File::kDifferent;
538 } 530 }
539 531
540 } // namespace bin 532 } // namespace bin
541 } // namespace dart 533 } // namespace dart
542 534
543 #endif // defined(TARGET_OS_ANDROID) 535 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/file_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698