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

Side by Side Diff: runtime/bin/file_fuchsia.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 | « runtime/bin/file_android.cc ('k') | runtime/bin/file_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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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_FUCHSIA) 6 #if defined(TARGET_OS_FUCHSIA)
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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 FDUtils::SaveErrorAndClose(fd); 241 FDUtils::SaveErrorAndClose(fd);
242 return is_file; 242 return is_file;
243 } 243 }
244 244
245 245
246 bool File::CreateLink(const char* name, const char* target) { 246 bool File::CreateLink(const char* name, const char* target) {
247 return NO_RETRY_EXPECTED(symlink(target, name)) == 0; 247 return NO_RETRY_EXPECTED(symlink(target, name)) == 0;
248 } 248 }
249 249
250 250
251 bool File::Delete(const char* name) { 251 File::Type File::GetType(const char* pathname, bool follow_links) {
252 File::Type type = File::GetType(name, true); 252 struct stat entry_info;
253 if (type == kIsFile) { 253 int stat_success;
254 return NO_RETRY_EXPECTED(unlink(name)) == 0; 254 if (follow_links) {
255 } else if (type == kIsDirectory) { 255 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
256 errno = EISDIR;
257 } else { 256 } else {
258 errno = ENOENT; 257 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
258 }
259 if (stat_success == -1) {
260 return File::kDoesNotExist;
261 }
262 if (S_ISDIR(entry_info.st_mode)) {
263 return File::kIsDirectory;
264 }
265 if (S_ISREG(entry_info.st_mode)) {
266 return File::kIsFile;
267 }
268 if (S_ISLNK(entry_info.st_mode)) {
269 return File::kIsLink;
270 }
271 return File::kDoesNotExist;
272 }
273
274
275 static bool CheckTypeAndSetErrno(const char* name,
276 File::Type expected,
277 bool follow_links) {
278 File::Type actual = File::GetType(name, follow_links);
279 if (actual == expected) {
280 return true;
281 }
282 switch (actual) {
283 case File::kIsDirectory:
284 errno = EISDIR;
285 break;
286 case File::kDoesNotExist:
287 errno = ENOENT;
288 break;
289 default:
290 errno = EINVAL;
291 break;
259 } 292 }
260 return false; 293 return false;
261 } 294 }
262 295
263 296
297 bool File::Delete(const char* name) {
298 return CheckTypeAndSetErrno(name, kIsFile, true) &&
299 (NO_RETRY_EXPECTED(unlink(name)) == 0);
300 }
301
302
264 bool File::DeleteLink(const char* name) { 303 bool File::DeleteLink(const char* name) {
265 File::Type type = File::GetType(name, false); 304 return CheckTypeAndSetErrno(name, kIsLink, false) &&
266 if (type == kIsLink) { 305 (NO_RETRY_EXPECTED(unlink(name)) == 0);
267 return NO_RETRY_EXPECTED(unlink(name)) == 0;
268 }
269 errno = EINVAL;
270 return false;
271 } 306 }
272 307
273 308
274 bool File::Rename(const char* old_path, const char* new_path) { 309 bool File::Rename(const char* old_path, const char* new_path) {
275 File::Type type = File::GetType(old_path, true); 310 return CheckTypeAndSetErrno(old_path, kIsFile, true) &&
276 if (type == kIsFile) { 311 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
277 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
278 } else if (type == kIsDirectory) {
279 errno = EISDIR;
280 } else {
281 errno = ENOENT;
282 }
283 return false;
284 } 312 }
285 313
286 314
287 bool File::RenameLink(const char* old_path, const char* new_path) { 315 bool File::RenameLink(const char* old_path, const char* new_path) {
288 File::Type type = File::GetType(old_path, false); 316 return CheckTypeAndSetErrno(old_path, kIsLink, false) &&
289 if (type == kIsLink) { 317 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
290 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
291 } else if (type == kIsDirectory) {
292 errno = EISDIR;
293 } else {
294 errno = EINVAL;
295 }
296 return false;
297 } 318 }
298 319
299 320
300 bool File::Copy(const char* old_path, const char* new_path) { 321 bool File::Copy(const char* old_path, const char* new_path) {
301 File::Type type = File::GetType(old_path, true); 322 if (!CheckTypeAndSetErrno(old_path, kIsFile, true)) {
302 if (type == kIsFile) { 323 return false;
303 struct stat64 st; 324 }
304 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) { 325 struct stat64 st;
305 return false; 326 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) {
327 return false;
328 }
329 int old_fd = NO_RETRY_EXPECTED(open64(old_path, O_RDONLY | O_CLOEXEC));
330 if (old_fd < 0) {
331 return false;
332 }
333 int new_fd = NO_RETRY_EXPECTED(
334 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
335 if (new_fd < 0) {
336 VOID_TEMP_FAILURE_RETRY(close(old_fd));
337 return false;
338 }
339 // TODO(MG-429): Use sendfile/copyfile or equivalent when there is one.
340 intptr_t result;
341 const intptr_t kBufferSize = 8 * KB;
342 uint8_t buffer[kBufferSize];
343 while ((result = NO_RETRY_EXPECTED(read(old_fd, buffer, kBufferSize))) > 0) {
344 int wrote = NO_RETRY_EXPECTED(write(new_fd, buffer, result));
345 if (wrote != result) {
346 result = -1;
347 break;
306 } 348 }
307 int old_fd = NO_RETRY_EXPECTED(open64(old_path, O_RDONLY | O_CLOEXEC));
308 if (old_fd < 0) {
309 return false;
310 }
311 int new_fd = NO_RETRY_EXPECTED(
312 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
313 if (new_fd < 0) {
314 VOID_TEMP_FAILURE_RETRY(close(old_fd));
315 return false;
316 }
317 // TODO(MG-429): Use sendfile/copyfile or equivalent when there is one.
318 intptr_t result;
319 const intptr_t kBufferSize = 8 * KB;
320 uint8_t buffer[kBufferSize];
321 while ((result = NO_RETRY_EXPECTED(read(old_fd, buffer, kBufferSize))) >
322 0) {
323 int wrote = NO_RETRY_EXPECTED(write(new_fd, buffer, result));
324 if (wrote != result) {
325 result = -1;
326 break;
327 }
328 }
329 FDUtils::SaveErrorAndClose(old_fd);
330 FDUtils::SaveErrorAndClose(new_fd);
331 if (result < 0) {
332 int e = errno;
333 VOID_NO_RETRY_EXPECTED(unlink(new_path));
334 errno = e;
335 return false;
336 }
337 return true;
338 } else if (type == kIsDirectory) {
339 errno = EISDIR;
340 } else {
341 errno = ENOENT;
342 } 349 }
343 return false; 350 FDUtils::SaveErrorAndClose(old_fd);
351 FDUtils::SaveErrorAndClose(new_fd);
352 if (result < 0) {
353 int e = errno;
354 VOID_NO_RETRY_EXPECTED(unlink(new_path));
355 errno = e;
356 return false;
357 }
358 return true;
344 } 359 }
345 360
346 361
347 int64_t File::LengthFromPath(const char* name) { 362 int64_t File::LengthFromPath(const char* name) {
348 struct stat st; 363 struct stat st;
349 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 364 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
350 // Signal an error if it's a directory. 365 // Signal an error if it's a directory.
351 if (S_ISDIR(st.st_mode)) { 366 if (S_ISDIR(st.st_mode)) {
352 errno = EISDIR; 367 errno = EISDIR;
353 return -1; 368 return -1;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 if (S_ISSOCK(buf.st_mode)) { 487 if (S_ISSOCK(buf.st_mode)) {
473 return kSocket; 488 return kSocket;
474 } 489 }
475 if (S_ISREG(buf.st_mode)) { 490 if (S_ISREG(buf.st_mode)) {
476 return kFile; 491 return kFile;
477 } 492 }
478 return kOther; 493 return kOther;
479 } 494 }
480 495
481 496
482 File::Type File::GetType(const char* pathname, bool follow_links) {
483 struct stat entry_info;
484 int stat_success;
485 if (follow_links) {
486 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
487 } else {
488 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
489 }
490 if (stat_success == -1) {
491 return File::kDoesNotExist;
492 }
493 if (S_ISDIR(entry_info.st_mode)) {
494 return File::kIsDirectory;
495 }
496 if (S_ISREG(entry_info.st_mode)) {
497 return File::kIsFile;
498 }
499 if (S_ISLNK(entry_info.st_mode)) {
500 return File::kIsLink;
501 }
502 return File::kDoesNotExist;
503 }
504
505
506 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { 497 File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
507 struct stat file_1_info; 498 struct stat file_1_info;
508 struct stat file_2_info; 499 struct stat file_2_info;
509 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || 500 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
510 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { 501 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
511 return File::kError; 502 return File::kError;
512 } 503 }
513 return ((file_1_info.st_ino == file_2_info.st_ino) && 504 return ((file_1_info.st_ino == file_2_info.st_ino) &&
514 (file_1_info.st_dev == file_2_info.st_dev)) 505 (file_1_info.st_dev == file_2_info.st_dev))
515 ? File::kIdentical 506 ? File::kIdentical
516 : File::kDifferent; 507 : File::kDifferent;
517 } 508 }
518 509
519 } // namespace bin 510 } // namespace bin
520 } // namespace dart 511 } // namespace dart
521 512
522 #endif // defined(TARGET_OS_FUCHSIA) 513 #endif // defined(TARGET_OS_FUCHSIA)
OLDNEW
« no previous file with comments | « runtime/bin/file_android.cc ('k') | runtime/bin/file_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698