copy_file read/write loop implementation
| 731 | |
| 732 | //! copy_file read/write loop implementation |
| 733 | int copy_file_data_read_write_impl(int infile, int outfile, char* buf, std::size_t buf_size) |
| 734 | { |
| 735 | #if defined(BOOST_FILESYSTEM_HAS_POSIX_FADVISE) |
| 736 | ::posix_fadvise(infile, 0, 0, POSIX_FADV_SEQUENTIAL); |
| 737 | #endif |
| 738 | |
| 739 | // Don't use file size to limit the amount of data to copy since some filesystems, like procfs or sysfs, |
| 740 | // provide files with generated content and indicate that their size is zero or 4096. Just copy as much data |
| 741 | // as we can read from the input file. |
| 742 | while (true) |
| 743 | { |
| 744 | ssize_t sz_read = ::read(infile, buf, buf_size); |
| 745 | if (sz_read == 0) |
| 746 | break; |
| 747 | if (BOOST_UNLIKELY(sz_read < 0)) |
| 748 | { |
| 749 | int err = errno; |
| 750 | if (err == EINTR) |
| 751 | continue; |
| 752 | return err; |
| 753 | } |
| 754 | |
| 755 | // Allow for partial writes - see Advanced Unix Programming (2nd Ed.), |
| 756 | // Marc Rochkind, Addison-Wesley, 2004, page 94 |
| 757 | for (ssize_t sz_wrote = 0; sz_wrote < sz_read;) |
| 758 | { |
| 759 | ssize_t sz = ::write(outfile, buf + sz_wrote, static_cast< std::size_t >(sz_read - sz_wrote)); |
| 760 | if (BOOST_UNLIKELY(sz < 0)) |
| 761 | { |
| 762 | int err = errno; |
| 763 | if (err == EINTR) |
| 764 | continue; |
| 765 | return err; |
| 766 | } |
| 767 | |
| 768 | sz_wrote += sz; |
| 769 | } |
| 770 | } |
| 771 | |
| 772 | return 0; |
| 773 | } |
| 774 | |
| 775 | //! copy_file implementation that uses read/write loop (fallback using a stack buffer) |
| 776 | int copy_file_data_read_write_stack_buf(int infile, int outfile) |
no outgoing calls
no test coverage detected