Creates a FileWriter for |fd| and prepare to write |entry| to it, guaranteeing that the file descriptor is valid and that there's enough space on the volume to write out the entry completely and that the file is truncated to the correct length (no truncation if |fd| references a block device). Returns a valid FileWriter on success, |nullptr| if an error occurred.
| 786 | // |
| 787 | // Returns a valid FileWriter on success, |nullptr| if an error occurred. |
| 788 | static FileWriter Create(int fd, const ZipEntry* entry) { |
| 789 | const uint32_t declared_length = entry->uncompressed_length; |
| 790 | const off64_t current_offset = lseek64(fd, 0, SEEK_CUR); |
| 791 | if (current_offset == -1) { |
| 792 | //chensenhua ALOGW("Zip: unable to seek to current location on fd %d: %s", fd, strerror(errno)); |
| 793 | return FileWriter{}; |
| 794 | } |
| 795 | |
| 796 | int result = 0; |
| 797 | #if defined(__linux__) |
| 798 | if (declared_length > 0) { |
| 799 | // Make sure we have enough space on the volume to extract the compressed |
| 800 | // entry. Note that the call to ftruncate below will change the file size but |
| 801 | // will not allocate space on disk and this call to fallocate will not |
| 802 | // change the file size. |
| 803 | // Note: fallocate is only supported by the following filesystems - |
| 804 | // btrfs, ext4, ocfs2, and xfs. Therefore fallocate might fail with |
| 805 | // EOPNOTSUPP error when issued in other filesystems. |
| 806 | // Hence, check for the return error code before concluding that the |
| 807 | // disk does not have enough space. |
| 808 | result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length)); |
| 809 | if (result == -1 && errno == ENOSPC) { |
| 810 | //chensenhua ALOGW("Zip: unable to allocate %" PRId64 " bytes at offset %" PRId64 ": %s", |
| 811 | //chensenhua static_cast<int64_t>(declared_length), static_cast<int64_t>(current_offset), |
| 812 | //chensenhua strerror(errno)); |
| 813 | return FileWriter{}; |
| 814 | } |
| 815 | } |
| 816 | #endif // __linux__ |
| 817 | |
| 818 | struct stat sb; |
| 819 | if (fstat(fd, &sb) == -1) { |
| 820 | //chensenhua ALOGW("Zip: unable to fstat file: %s", strerror(errno)); |
| 821 | return FileWriter{}; |
| 822 | } |
| 823 | |
| 824 | // Block device doesn't support ftruncate(2). |
| 825 | if (!S_ISBLK(sb.st_mode)) { |
| 826 | result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset)); |
| 827 | if (result == -1) { |
| 828 | //chensenhua ALOGW("Zip: unable to truncate file to %" PRId64 ": %s", |
| 829 | //chensenhua static_cast<int64_t>(declared_length + current_offset), strerror(errno)); |
| 830 | return FileWriter{}; |
| 831 | } |
| 832 | } |
| 833 | |
| 834 | return FileWriter(fd, declared_length); |
| 835 | } |
| 836 | |
| 837 | FileWriter(FileWriter&& other) |
| 838 | : fd_(other.fd_), |
nothing calls this directly
no test coverage detected