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

Side by Side Diff: src/xz/file_io.c

Issue 62403002: Update XZ Utils to 5.0.5 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/xz/
Patch Set: Created 7 years, 1 month 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 | « src/xz/coder.c ('k') | src/xz/list.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /////////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////////
2 // 2 //
3 /// \file file_io.c 3 /// \file file_io.c
4 /// \brief File opening, unlinking, and closing 4 /// \brief File opening, unlinking, and closing
5 // 5 //
6 // Author: Lasse Collin 6 // Author: Lasse Collin
7 // 7 //
8 // This file has been put into the public domain. 8 // This file has been put into the public domain.
9 // You can do whatever you want with this file. 9 // You can do whatever you want with this file.
10 // 10 //
(...skipping 23 matching lines...) Expand all
34 34
35 #ifndef O_NOCTTY 35 #ifndef O_NOCTTY
36 # define O_NOCTTY 0 36 # define O_NOCTTY 0
37 #endif 37 #endif
38 38
39 39
40 /// If true, try to create sparse files when decompressing. 40 /// If true, try to create sparse files when decompressing.
41 static bool try_sparse = true; 41 static bool try_sparse = true;
42 42
43 #ifndef TUKLIB_DOSLIKE 43 #ifndef TUKLIB_DOSLIKE
44 /// File status flags of standard output. This is used by io_open_dest() 44 /// Original file status flags of standard output. This is used by
45 /// and io_close_dest(). 45 /// io_open_dest() and io_close_dest() to save and restore the flags.
46 static int stdout_flags = 0; 46 static int stdout_flags;
47 static bool restore_stdout_flags = false;
47 #endif 48 #endif
48 49
49 50
50 static bool io_write_buf(file_pair *pair, const uint8_t *buf, size_t size); 51 static bool io_write_buf(file_pair *pair, const uint8_t *buf, size_t size);
51 52
52 53
53 extern void 54 extern void
54 io_init(void) 55 io_init(void)
55 { 56 {
56 // Make sure that stdin, stdout, and stderr are connected to 57 // Make sure that stdin, stdout, and stderr are connected to
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 391
391 # if defined(__FreeBSD__) || defined(__DragonFly__) 392 # if defined(__FreeBSD__) || defined(__DragonFly__)
392 if (errno == EMLINK) 393 if (errno == EMLINK)
393 was_symlink = true; 394 was_symlink = true;
394 395
395 # elif defined(__digital__) && defined(__unix__) 396 # elif defined(__digital__) && defined(__unix__)
396 if (errno == ENOTSUP) 397 if (errno == ENOTSUP)
397 was_symlink = true; 398 was_symlink = true;
398 399
399 # elif defined(__NetBSD__) 400 # elif defined(__NetBSD__)
400 // As of 2010-09-05, NetBSD doesn't document what errno is
401 // used with O_NOFOLLOW. It is EFTYPE though, and I
402 // understood that is very unlikely to change even though
403 // it is undocumented.
404 if (errno == EFTYPE) 401 if (errno == EFTYPE)
405 was_symlink = true; 402 was_symlink = true;
406 403
407 # else 404 # else
408 if (errno == ELOOP && !follow_symlinks) { 405 if (errno == ELOOP && !follow_symlinks) {
409 const int saved_errno = errno; 406 const int saved_errno = errno;
410 struct stat st; 407 struct stat st;
411 if (lstat(pair->src_name, &st) == 0 408 if (lstat(pair->src_name, &st) == 0
412 && S_ISLNK(st.st_mode)) 409 && S_ISLNK(st.st_mode))
413 was_symlink = true; 410 was_symlink = true;
(...skipping 20 matching lines...) Expand all
434 // Drop O_NONBLOCK, which is used only when we are accepting only 431 // Drop O_NONBLOCK, which is used only when we are accepting only
435 // regular files. After the open() call, we want things to block 432 // regular files. After the open() call, we want things to block
436 // instead of giving EAGAIN. 433 // instead of giving EAGAIN.
437 if (reg_files_only) { 434 if (reg_files_only) {
438 flags = fcntl(pair->src_fd, F_GETFL); 435 flags = fcntl(pair->src_fd, F_GETFL);
439 if (flags == -1) 436 if (flags == -1)
440 goto error_msg; 437 goto error_msg;
441 438
442 flags &= ~O_NONBLOCK; 439 flags &= ~O_NONBLOCK;
443 440
444 » » if (fcntl(pair->src_fd, F_SETFL, flags)) 441 » » if (fcntl(pair->src_fd, F_SETFL, flags) == -1)
445 goto error_msg; 442 goto error_msg;
446 } 443 }
447 #endif 444 #endif
448 445
449 // Stat the source file. We need the result also when we copy 446 // Stat the source file. We need the result also when we copy
450 // the permissions, and when unlinking. 447 // the permissions, and when unlinking.
451 if (fstat(pair->src_fd, &pair->src_st)) 448 if (fstat(pair->src_fd, &pair->src_st))
452 goto error_msg; 449 goto error_msg;
453 450
454 if (S_ISDIR(pair->src_st.st_mode)) { 451 if (S_ISDIR(pair->src_st.st_mode)) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 // - O_APPEND may be active. 624 // - O_APPEND may be active.
628 // 625 //
629 // TODO: I'm keeping this disabled for DOS-like systems 626 // TODO: I'm keeping this disabled for DOS-like systems
630 // for now. FAT doesn't support sparse files, but NTFS 627 // for now. FAT doesn't support sparse files, but NTFS
631 // does, so maybe this should be enabled on Windows after 628 // does, so maybe this should be enabled on Windows after
632 // some testing. 629 // some testing.
633 if (pair->dest_fd == STDOUT_FILENO) { 630 if (pair->dest_fd == STDOUT_FILENO) {
634 if (!S_ISREG(pair->dest_st.st_mode)) 631 if (!S_ISREG(pair->dest_st.st_mode))
635 return false; 632 return false;
636 633
637 » » » const int flags = fcntl(STDOUT_FILENO, F_GETFL); 634 » » » stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
638 » » » if (flags == -1) 635 » » » if (stdout_flags == -1)
639 return false; 636 return false;
640 637
641 » » » if (flags & O_APPEND) { 638 » » » if (stdout_flags & O_APPEND) {
642 // Creating a sparse file is not possible 639 // Creating a sparse file is not possible
643 // when O_APPEND is active (it's used by 640 // when O_APPEND is active (it's used by
644 // shell's >> redirection). As I understand 641 // shell's >> redirection). As I understand
645 // it, it is safe to temporarily disable 642 // it, it is safe to temporarily disable
646 // O_APPEND in xz, because if someone 643 // O_APPEND in xz, because if someone
647 // happened to write to the same file at the 644 // happened to write to the same file at the
648 // same time, results would be bad anyway 645 // same time, results would be bad anyway
649 // (users shouldn't assume that xz uses any 646 // (users shouldn't assume that xz uses any
650 // specific block size when writing data). 647 // specific block size when writing data).
651 // 648 //
652 // The write position may be something else 649 // The write position may be something else
653 // than the end of the file, so we must fix 650 // than the end of the file, so we must fix
654 // it to start writing at the end of the file 651 // it to start writing at the end of the file
655 // to imitate O_APPEND. 652 // to imitate O_APPEND.
656 if (lseek(STDOUT_FILENO, 0, SEEK_END) == -1) 653 if (lseek(STDOUT_FILENO, 0, SEEK_END) == -1)
657 return false; 654 return false;
658 655
659 if (fcntl(STDOUT_FILENO, F_SETFL, 656 if (fcntl(STDOUT_FILENO, F_SETFL,
660 » » » » » » stdout_flags & ~O_APPEND)) 657 » » » » » » stdout_flags & ~O_APPEND)
658 » » » » » » == -1)
661 return false; 659 return false;
662 660
663 » » » » // Remember the flags so that io_close_dest() 661 » » » » // Disabling O_APPEND succeeded. Mark
664 » » » » // can restore them. 662 » » » » // that the flags should be restored
665 » » » » stdout_flags = flags; 663 » » » » // in io_close_dest().
664 » » » » restore_stdout_flags = true;
666 665
667 } else if (lseek(STDOUT_FILENO, 0, SEEK_CUR) 666 } else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
668 != pair->dest_st.st_size) { 667 != pair->dest_st.st_size) {
669 // Writing won't start exactly at the end 668 // Writing won't start exactly at the end
670 // of the file. We cannot use sparse output, 669 // of the file. We cannot use sparse output,
671 // because it would probably corrupt the file. 670 // because it would probably corrupt the file.
672 return false; 671 return false;
673 } 672 }
674 } 673 }
675 674
(...skipping 20 matching lines...) Expand all
696 /// \param pair File whose dest_fd should be closed 695 /// \param pair File whose dest_fd should be closed
697 /// \param success If false, the file will be removed from the disk. 696 /// \param success If false, the file will be removed from the disk.
698 /// 697 ///
699 /// \return Zero if closing succeeds. On error, -1 is returned and 698 /// \return Zero if closing succeeds. On error, -1 is returned and
700 /// error message printed. 699 /// error message printed.
701 static bool 700 static bool
702 io_close_dest(file_pair *pair, bool success) 701 io_close_dest(file_pair *pair, bool success)
703 { 702 {
704 #ifndef TUKLIB_DOSLIKE 703 #ifndef TUKLIB_DOSLIKE
705 // If io_open_dest() has disabled O_APPEND, restore it here. 704 // If io_open_dest() has disabled O_APPEND, restore it here.
706 » if (stdout_flags != 0) { 705 » if (restore_stdout_flags) {
707 assert(pair->dest_fd == STDOUT_FILENO); 706 assert(pair->dest_fd == STDOUT_FILENO);
708 707
709 » » const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags); 708 » » restore_stdout_flags = false;
710 » » stdout_flags = 0;
711 709
712 » » if (fail) { 710 » » if (fcntl(STDOUT_FILENO, F_SETFL, stdout_flags) == -1) {
713 message_error(_("Error restoring the O_APPEND flag " 711 message_error(_("Error restoring the O_APPEND flag "
714 "to standard output: %s"), 712 "to standard output: %s"),
715 strerror(errno)); 713 strerror(errno));
716 return true; 714 return true;
717 } 715 }
718 } 716 }
719 #endif 717 #endif
720 718
721 if (pair->dest_fd == -1 || pair->dest_fd == STDOUT_FILENO) 719 if (pair->dest_fd == -1 || pair->dest_fd == STDOUT_FILENO)
722 return false; 720 return false;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 static bool 873 static bool
876 io_write_buf(file_pair *pair, const uint8_t *buf, size_t size) 874 io_write_buf(file_pair *pair, const uint8_t *buf, size_t size)
877 { 875 {
878 assert(size < SSIZE_MAX); 876 assert(size < SSIZE_MAX);
879 877
880 while (size > 0) { 878 while (size > 0) {
881 const ssize_t amount = write(pair->dest_fd, buf, size); 879 const ssize_t amount = write(pair->dest_fd, buf, size);
882 if (amount == -1) { 880 if (amount == -1) {
883 if (errno == EINTR) { 881 if (errno == EINTR) {
884 if (user_abort) 882 if (user_abort)
885 » » » » » return -1; 883 » » » » » return true;
886 884
887 continue; 885 continue;
888 } 886 }
889 887
890 // Handle broken pipe specially. gzip and bzip2 888 // Handle broken pipe specially. gzip and bzip2
891 // don't print anything on SIGPIPE. In addition, 889 // don't print anything on SIGPIPE. In addition,
892 // gzip --quiet uses exit status 2 (warning) on 890 // gzip --quiet uses exit status 2 (warning) on
893 // broken pipe instead of whatever raise(SIGPIPE) 891 // broken pipe instead of whatever raise(SIGPIPE)
894 // would make it return. It is there to hide "Broken 892 // would make it return. It is there to hide "Broken
895 // pipe" message on some old shells (probably old 893 // pipe" message on some old shells (probably old
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 strerror(errno)); 946 strerror(errno));
949 return true; 947 return true;
950 } 948 }
951 949
952 pair->dest_pending_sparse = 0; 950 pair->dest_pending_sparse = 0;
953 } 951 }
954 } 952 }
955 953
956 return io_write_buf(pair, buf->u8, size); 954 return io_write_buf(pair, buf->u8, size);
957 } 955 }
OLDNEW
« no previous file with comments | « src/xz/coder.c ('k') | src/xz/list.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698