archive_read_data_into_fd.c revision 228761
153451Speter/*- 253473Sobrien * Copyright (c) 2003-2007 Tim Kientzle 353451Speter * All rights reserved. 453451Speter * 553451Speter * Redistribution and use in source and binary forms, with or without 653451Speter * modification, are permitted provided that the following conditions 753451Speter * are met: 853451Speter * 1. Redistributions of source code must retain the above copyright 953451Speter * notice, this list of conditions and the following disclaimer. 1053451Speter * 2. Redistributions in binary form must reproduce the above copyright 1153451Speter * notice, this list of conditions and the following disclaimer in the 1253451Speter * documentation and/or other materials provided with the distribution. 1353451Speter * 1453451Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 1553451Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1653473Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1753451Speter * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 1853451Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1953451Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2053473Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2153473Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2253451Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2353451Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2453451Speter */ 2553451Speter 2653451Speter#include "archive_platform.h" 27131557Stjr__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $"); 2853473Sobrien 2953473Sobrien#ifdef HAVE_SYS_TYPES_H 3053473Sobrien#include <sys/types.h> 3153473Sobrien#endif 3253473Sobrien#ifdef HAVE_ERRNO_H 3353473Sobrien#include <errno.h> 3453473Sobrien#endif 3553473Sobrien#ifdef HAVE_UNISTD_H 3653473Sobrien#include <unistd.h> 37131557Stjr#endif 38131557Stjr 39131557Stjr#include "archive.h" 40131557Stjr#include "archive_private.h" 41131557Stjr 42131557Stjr/* Maximum amount of data to write at one time. */ 43131557Stjr#define MAX_WRITE (1024 * 1024) 44131557Stjr 4553473Sobrien/* 4653473Sobrien * This implementation minimizes copying of data and is sparse-file aware. 4753473Sobrien */ 4853451Speterint 4953473Sobrienarchive_read_data_into_fd(struct archive *a, int fd) 5053451Speter{ 5153473Sobrien int r; 5253451Speter const void *buff; 5353451Speter size_t size, bytes_to_write; 5453451Speter ssize_t bytes_written, total_written; 5553451Speter off_t offset; 5653451Speter off_t output_offset; 5753473Sobrien 5853451Speter __archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, "archive_read_data_into_fd"); 5953473Sobrien 6053451Speter total_written = 0; 6153451Speter output_offset = 0; 6253451Speter 6353451Speter while ((r = archive_read_data_block(a, &buff, &size, &offset)) == 6453451Speter ARCHIVE_OK) { 6553451Speter const char *p = buff; 6653451Speter if (offset > output_offset) { 6753451Speter output_offset = lseek(fd, 6853451Speter offset - output_offset, SEEK_CUR); 6953451Speter if (output_offset != offset) { 7053451Speter archive_set_error(a, errno, "Seek error"); 7153451Speter return (ARCHIVE_FATAL); 7253451Speter } 7353451Speter } 7453451Speter while (size > 0) { 7553451Speter bytes_to_write = size; 7653451Speter if (bytes_to_write > MAX_WRITE) 7753451Speter bytes_to_write = MAX_WRITE; 7853451Speter bytes_written = write(fd, p, bytes_to_write); 7953451Speter if (bytes_written < 0) { 8053451Speter archive_set_error(a, errno, "Write error"); 8153451Speter return (ARCHIVE_FATAL); 8253451Speter } 8353451Speter output_offset += bytes_written; 8453451Speter total_written += bytes_written; 8553451Speter p += bytes_written; 8653451Speter size -= bytes_written; 8753451Speter } 8853451Speter } 8953451Speter 9053451Speter if (r != ARCHIVE_EOF) 9153451Speter return (r); 9253451Speter return (ARCHIVE_OK); 9353451Speter} 9453451Speter