Date: Sun, 7 Dec 2008 12:06:05 GMT From: Ed Schouten <ed@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 154248 for review Message-ID: <200812071206.mB7C65DK060769@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154248 Change 154248 by ed@ed_flippo on 2008/12/07 12:06:05 IFC. Affected files ... .. //depot/projects/mpsafetty/lib/libarchive/archive.h#4 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_check_magic.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_endian.h#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_entry.h#5 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_platform.h#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_private.h#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_private.h#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_all.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_bzip2.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_compress.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_gzip.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_none.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_compression_program.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_ar.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_cpio.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_empty.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_iso9660.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_mtree.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_tar.c#4 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_read_support_format_zip.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_string.c#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_string.h#2 integrate .. //depot/projects/mpsafetty/lib/libarchive/archive_write_disk.c#11 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/Makefile#6 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_bzip2.c#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_bzip2_1.tbz.uu#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_bzip2_2.tbz.uu#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_gzip.c#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_gzip_1.tgz.uu#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_compat_gzip_2.tgz.uu#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_fuzz.c#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_fuzz_1.iso.uu#1 branch .. //depot/projects/mpsafetty/lib/libarchive/test/test_read_format_cpio_bin_bz2.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/test_read_format_gtar_sparse.c#4 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/test_read_pax_truncated.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/test_write_disk_perms.c#3 integrate .. //depot/projects/mpsafetty/lib/libarchive/test/test_write_format_cpio.c#3 integrate .. //depot/projects/mpsafetty/lib/libc/string/Makefile.inc#3 integrate .. //depot/projects/mpsafetty/lib/libc/string/Symbol.map#3 integrate .. //depot/projects/mpsafetty/lib/libc/string/strdup.3#2 integrate .. //depot/projects/mpsafetty/lib/libc/string/strndup.c#1 branch .. //depot/projects/mpsafetty/lib/libthr/thread/thr_rtld.c#3 integrate .. //depot/projects/mpsafetty/lib/libutil/Makefile#5 integrate .. //depot/projects/mpsafetty/lib/libutil/kinfo_getfile.3#1 branch .. //depot/projects/mpsafetty/lib/libutil/kinfo_getvmmap.3#1 branch .. //depot/projects/mpsafetty/share/man/man4/man4.powerpc/Makefile#2 integrate .. //depot/projects/mpsafetty/share/man/man4/man4.powerpc/pmu.4#1 branch .. //depot/projects/mpsafetty/share/man/man7/ports.7#2 integrate .. //depot/projects/mpsafetty/sys/amd64/amd64/pmap.c#12 integrate .. //depot/projects/mpsafetty/sys/boot/common/loader.8#2 integrate .. //depot/projects/mpsafetty/sys/boot/zfs/Makefile#2 integrate .. //depot/projects/mpsafetty/sys/dev/adb/adb.h#2 integrate .. //depot/projects/mpsafetty/sys/dev/adb/adb_bus.c#4 integrate .. //depot/projects/mpsafetty/sys/dev/adb/adb_kbd.c#2 integrate .. //depot/projects/mpsafetty/sys/dev/adb/adb_mouse.c#4 integrate .. //depot/projects/mpsafetty/sys/dev/adb/adbvar.h#3 integrate .. //depot/projects/mpsafetty/sys/dev/ae/if_ae.c#2 integrate .. //depot/projects/mpsafetty/sys/dev/cxgb/common/cxgb_t3_hw.c#8 integrate .. //depot/projects/mpsafetty/sys/dev/cxgb/cxgb_main.c#14 integrate .. //depot/projects/mpsafetty/sys/dev/mmc/mmc.c#7 integrate .. //depot/projects/mpsafetty/sys/dev/mmc/mmcsd.c#9 integrate .. //depot/projects/mpsafetty/sys/dev/sdhci/sdhci.c#4 integrate .. //depot/projects/mpsafetty/sys/dev/usb/if_ural.c#3 integrate .. //depot/projects/mpsafetty/sys/geom/journal/g_journal.c#4 integrate .. //depot/projects/mpsafetty/sys/geom/journal/g_journal.h#2 integrate .. //depot/projects/mpsafetty/sys/i386/include/atomic.h#3 integrate .. //depot/projects/mpsafetty/sys/kern/kern_exec.c#10 integrate .. //depot/projects/mpsafetty/sys/kern/kern_exit.c#8 integrate .. //depot/projects/mpsafetty/sys/kern/kern_fork.c#5 integrate .. //depot/projects/mpsafetty/sys/kern/kern_proc.c#13 integrate .. //depot/projects/mpsafetty/sys/libkern/iconv.c#2 integrate .. //depot/projects/mpsafetty/sys/netgraph/ng_mppc.c#3 integrate .. //depot/projects/mpsafetty/sys/netinet/if_ether.c#11 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp.h#3 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_asconf.c#4 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_asconf.h#3 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_auth.c#2 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_auth.h#2 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_constants.h#5 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_header.h#2 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_indata.c#5 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_indata.h#3 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_input.c#5 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_os_bsd.h#7 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_output.c#8 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_output.h#3 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_pcb.c#8 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_pcb.h#5 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_structs.h#2 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_sysctl.c#3 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_sysctl.h#4 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_timer.c#6 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_uio.h#4 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_usrreq.c#6 integrate .. //depot/projects/mpsafetty/sys/netinet/sctp_var.h#5 integrate .. //depot/projects/mpsafetty/sys/netinet/sctputil.c#8 integrate .. //depot/projects/mpsafetty/sys/netinet/sctputil.h#3 integrate .. //depot/projects/mpsafetty/sys/netinet6/sctp6_usrreq.c#3 integrate .. //depot/projects/mpsafetty/sys/powerpc/powermac/cuda.c#3 integrate .. //depot/projects/mpsafetty/sys/powerpc/powermac/cudavar.h#2 integrate .. //depot/projects/mpsafetty/sys/powerpc/powermac/pmu.c#3 integrate .. //depot/projects/mpsafetty/sys/sys/proc.h#12 integrate .. //depot/projects/mpsafetty/tools/test/pthread_vfork/pthread_vfork_test.c#1 branch .. //depot/projects/mpsafetty/usr.bin/cpio/Makefile#2 integrate .. //depot/projects/mpsafetty/usr.bin/cpio/cmdline.c#3 integrate .. //depot/projects/mpsafetty/usr.bin/cpio/config_freebsd.h#2 integrate .. //depot/projects/mpsafetty/usr.bin/cpio/cpio.c#8 integrate .. //depot/projects/mpsafetty/usr.bin/cpio/cpio.h#5 integrate .. //depot/projects/mpsafetty/usr.bin/cpio/cpio_platform.h#2 integrate .. //depot/projects/mpsafetty/usr.bin/tar/Makefile#4 integrate .. //depot/projects/mpsafetty/usr.bin/tar/bsdtar.1#4 integrate .. //depot/projects/mpsafetty/usr.bin/tar/bsdtar.h#4 integrate .. //depot/projects/mpsafetty/usr.bin/tar/bsdtar_platform.h#2 integrate .. //depot/projects/mpsafetty/usr.bin/wc/wc.1#2 integrate .. //depot/projects/mpsafetty/usr.bin/wc/wc.c#2 integrate Differences ... ==== //depot/projects/mpsafetty/lib/libarchive/archive.h#4 (text+ko) ==== @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/lib/libarchive/archive.h,v 1.21 2008/09/18 04:19:06 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive.h,v 1.22 2008/12/06 06:17:18 kientzle Exp $ */ #ifndef ARCHIVE_H_INCLUDED @@ -82,7 +82,6 @@ # define __LA_DECL #endif - #ifdef __cplusplus extern "C" { #endif @@ -114,13 +113,13 @@ * (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000) * #endif */ -#define ARCHIVE_VERSION_NUMBER 2005005 +#define ARCHIVE_VERSION_NUMBER 2005903 __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_STRING "libarchive 2.5.5" +#define ARCHIVE_VERSION_STRING "libarchive 2.5.903a" __LA_DECL const char * archive_version_string(void); #if ARCHIVE_VERSION_NUMBER < 3000000 @@ -185,20 +184,37 @@ */ /* Returns pointer and size of next block of data from archive. */ -typedef __LA_SSIZE_T archive_read_callback(struct archive *, void *_client_data, - const void **_buffer); +typedef __LA_SSIZE_T archive_read_callback(struct archive *, + void *_client_data, const void **_buffer); + /* Skips at most request bytes from archive and returns the skipped amount */ #if ARCHIVE_VERSION_NUMBER < 2000000 -typedef __LA_SSIZE_T archive_skip_callback(struct archive *, void *_client_data, - size_t request); +/* Libarchive 1.0 used ssize_t for the return, which is only 32 bits + * on most 32-bit platforms; not large enough. */ +typedef __LA_SSIZE_T archive_skip_callback(struct archive *, + void *_client_data, size_t request); +#elif ARCHIVE_VERSION_NUMBER < 3000000 +/* Libarchive 2.0 used off_t here, but that is a bad idea on Linux and a + * few other platforms where off_t varies with build settings. */ +typedef off_t archive_skip_callback(struct archive *, + void *_client_data, off_t request); #else -typedef off_t archive_skip_callback(struct archive *, void *_client_data, - off_t request); +/* Libarchive 3.0 uses int64_t here, which is actually guaranteed to be + * 64 bits on every platform. */ +typedef __LA_INT64_T archive_skip_callback(struct archive *, + void *_client_data, __LA_INT64_T request); #endif + /* Returns size actually written, zero on EOF, -1 on error. */ -typedef __LA_SSIZE_T archive_write_callback(struct archive *, void *_client_data, - const void *_buffer, size_t _length); +typedef __LA_SSIZE_T archive_write_callback(struct archive *, + void *_client_data, + const void *_buffer, size_t _length); + +#if ARCHIVE_VERSION_NUMBER < 3000000 +/* Open callback is actually never needed; remove it in libarchive 3.0. */ typedef int archive_open_callback(struct archive *, void *_client_data); +#endif + typedef int archive_close_callback(struct archive *, void *_client_data); /* @@ -209,6 +225,7 @@ #define ARCHIVE_COMPRESSION_BZIP2 2 #define ARCHIVE_COMPRESSION_COMPRESS 3 #define ARCHIVE_COMPRESSION_PROGRAM 4 +#define ARCHIVE_COMPRESSION_LZMA 5 /* * Codes returned by archive_format. @@ -333,15 +350,23 @@ __LA_DECL __LA_INT64_T archive_read_header_position(struct archive *); /* Read data from the body of an entry. Similar to read(2). */ -__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *, void *, size_t); +__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *, + void *, size_t); + /* * A zero-copy version of archive_read_data that also exposes the file offset * of each returned block. Note that the client has no way to specify * the desired size of the block. The API does guarantee that offsets will * be strictly increasing and that returned blocks will not overlap. */ +#if ARCHIVE_VERSION_NUMBER < 3000000 +__LA_DECL int archive_read_data_block(struct archive *a, + const void **buff, size_t *size, off_t *offset); +#else __LA_DECL int archive_read_data_block(struct archive *a, - const void **buff, size_t *size, off_t *offset); + const void **buff, size_t *size, + __LA_INT64_T *offset); +#endif /*- * Some convenience functions that are built on archive_read_data: @@ -350,8 +375,8 @@ * 'into_fd': writes data to specified filedes */ __LA_DECL int archive_read_data_skip(struct archive *); -__LA_DECL int archive_read_data_into_buffer(struct archive *, void *buffer, - __LA_SSIZE_T len); +__LA_DECL int archive_read_data_into_buffer(struct archive *, + void *buffer, __LA_SSIZE_T len); __LA_DECL int archive_read_data_into_fd(struct archive *, int fd); /*- @@ -414,12 +439,11 @@ __LA_DECL int archive_read_close(struct archive *); /* Release all resources and destroy the object. */ /* Note that archive_read_finish will call archive_read_close for you. */ -#if ARCHIVE_VERSION_NUMBER >= 2000000 -__LA_DECL int archive_read_finish(struct archive *); -#else -/* Temporarily allow library to compile with either 1.x or 2.0 API. */ +#if ARCHIVE_VERSION_NUMBER < 2000000 /* Erroneously declared to return void in libarchive 1.x */ __LA_DECL void archive_read_finish(struct archive *); +#else +__LA_DECL int archive_read_finish(struct archive *); #endif /*- @@ -491,22 +515,36 @@ */ __LA_DECL int archive_write_header(struct archive *, struct archive_entry *); -#if ARCHIVE_VERSION_NUMBER >= 2000000 -__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *, const void *, size_t); +#if ARCHIVE_VERSION_NUMBER < 2000000 +/* This was erroneously declared to return "int" in libarchive 1.x. */ +__LA_DECL int archive_write_data(struct archive *, + const void *, size_t); +#else +/* Libarchive 2.0 and later return ssize_t here. */ +__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *, + const void *, size_t); +#endif + +#if ARCHIVE_VERSION_NUMBER < 3000000 +/* Libarchive 1.x and 2.x use off_t for the argument, but that's not + * stable on Linux. */ +__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *, + const void *, size_t, off_t); #else -/* Temporarily allow library to compile with either 1.x or 2.0 API. */ -/* This was erroneously declared to return "int" in libarchive 1.x. */ -__LA_DECL int archive_write_data(struct archive *, const void *, size_t); +/* Libarchive 3.0 uses explicit int64_t to ensure consistent 64-bit support. */ +__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *, + const void *, size_t, __LA_INT64_T); #endif -__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *, const void *, size_t, off_t); __LA_DECL int archive_write_finish_entry(struct archive *); __LA_DECL int archive_write_close(struct archive *); -#if ARCHIVE_VERSION_NUMBER >= 2000000 -__LA_DECL int archive_write_finish(struct archive *); -#else -/* Temporarily allow library to compile with either 1.x or 2.0 API. */ +#if ARCHIVE_VERSION_NUMBER < 2000000 /* Return value was incorrect in libarchive 1.x. */ __LA_DECL void archive_write_finish(struct archive *); +#else +/* Libarchive 2.x and later returns an error if this fails. */ +/* It can fail if the archive wasn't already closed, in which case + * archive_write_finish() will implicitly call archive_write_close(). */ +__LA_DECL int archive_write_finish(struct archive *); #endif /*- @@ -589,5 +627,9 @@ /* This is meaningless outside of this header. */ #undef __LA_DECL +#undef __LA_GID_T +#undef __LA_INT64_T +#undef __LA_SSIZE_T +#undef __LA_UID_T #endif /* !ARCHIVE_H_INCLUDED */ ==== //depot/projects/mpsafetty/lib/libarchive/archive_check_magic.c#2 (text+ko) ==== @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_check_magic.c,v 1.8 2007/04/02 00:15:45 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_check_magic.c,v 1.9 2008/12/06 05:52:01 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -46,7 +46,7 @@ static void errmsg(const char *m) { - write(STDERR_FILENO, m, strlen(m)); + write(2, m, strlen(m)); } static void ==== //depot/projects/mpsafetty/lib/libarchive/archive_endian.h#2 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libarchive/archive_endian.h,v 1.3 2008/05/26 17:00:22 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_endian.h,v 1.4 2008/12/06 06:12:24 kientzle Exp $ * * Borrowed from FreeBSD's <sys/endian.h> */ @@ -35,14 +35,14 @@ #define ARCHIVE_ENDIAN_H_INCLUDED -/* Watcom C++ doesn't support 'inline' in C code. (For any version?) */ -#if defined( __WATCOMC__ ) - #define inline -#endif - -/* Visual C++ 6.0 doesn't support 'inline' in C code. (Does VC7? VC8?) */ -#if defined(_MSC_VER) - #define inline +/* + * Disabling inline keyword for compilers known to choke on it: + * - Watcom C++ in C code. (For any version?) + * - SGI MIPSpro + * - Microsoft Visual C++ 6.0 (supposedly newer versions too) + */ +#if defined(__WATCOMC__) || defined(__sgi) || defined(_MSC_VER) +#define inline #endif /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ ==== //depot/projects/mpsafetty/lib/libarchive/archive_entry.h#5 (text+ko) ==== @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/lib/libarchive/archive_entry.h,v 1.30 2008/09/30 03:53:03 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_entry.h,v 1.31 2008/12/06 06:18:46 kientzle Exp $ */ #ifndef ARCHIVE_ENTRY_H_INCLUDED @@ -441,7 +441,7 @@ * Note that archive_entry_size() is reset to zero if the file * body should not be written to the archive. Pay attention! */ -__LA_DECL struct archive_entry_linkresolver; +struct archive_entry_linkresolver; /* * There are three different strategies for marking hardlinks. ==== //depot/projects/mpsafetty/lib/libarchive/archive_platform.h#3 (text+ko) ==== @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.31 2008/09/12 04:03:34 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.32 2008/12/06 05:53:05 kientzle Exp $ */ /* @@ -39,10 +39,7 @@ /* archive.h and archive_entry.h require this. */ #define __LIBARCHIVE_BUILD 1 -#ifdef _WIN32 -#include "config_windows.h" -#include "archive_windows.h" -#elif defined(PLATFORM_CONFIG_H) +#if defined(PLATFORM_CONFIG_H) /* Use hand-built config.h in environments that need it. */ #include PLATFORM_CONFIG_H #elif defined(HAVE_CONFIG_H) ==== //depot/projects/mpsafetty/lib/libarchive/archive_private.h#3 (text+ko) ==== @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/lib/libarchive/archive_private.h,v 1.30 2008/08/04 01:25:48 cperciva Exp $ + * $FreeBSD: src/lib/libarchive/archive_private.h,v 1.32 2008/12/06 06:23:37 kientzle Exp $ */ #ifndef ARCHIVE_PRIVATE_H_INCLUDED @@ -31,15 +31,22 @@ #include "archive.h" #include "archive_string.h" +#if defined(__GNUC__) && (__GNUC__ > 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) +#define __LA_DEAD __attribute__((__noreturn__)) +#else +#define __LA_DEAD +#endif + #define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU) #define ARCHIVE_READ_MAGIC (0xdeb0c5U) -#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) +#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) #define ARCHIVE_STATE_ANY 0xFFFFU #define ARCHIVE_STATE_NEW 1U #define ARCHIVE_STATE_HEADER 2U #define ARCHIVE_STATE_DATA 4U -#define ARCHIVE_STATE_DATA_END 8U +#define ARCHIVE_STATE_DATA_END 8U #define ARCHIVE_STATE_EOF 0x10U #define ARCHIVE_STATE_CLOSED 0x20U #define ARCHIVE_STATE_FATAL 0x8000U @@ -92,7 +99,7 @@ void __archive_check_magic(struct archive *, unsigned int magic, unsigned int state, const char *func); -void __archive_errx(int retvalue, const char *msg) __dead2; +void __archive_errx(int retvalue, const char *msg) __LA_DEAD; #define err_combine(a,b) ((a) < (b) ? (a) : (b)) ==== //depot/projects/mpsafetty/lib/libarchive/archive_read.c#2 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read.c,v 1.38 2008/03/12 04:58:32 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read.c,v 1.39 2008/12/06 06:45:15 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include <errno.h> @@ -53,9 +53,10 @@ #include "archive_private.h" #include "archive_read_private.h" -static void choose_decompressor(struct archive_read *, const void*, size_t); +#define minimum(a, b) (a < b ? a : b) + +static int build_stream(struct archive_read *); static int choose_format(struct archive_read *); -static off_t dummy_skip(struct archive_read *, off_t); /* * Allocate, initialize and return a struct archive object. @@ -74,8 +75,15 @@ a->archive.state = ARCHIVE_STATE_NEW; a->entry = archive_entry_new(); - /* We always support uncompressed archives. */ - archive_read_support_compression_none(&a->archive); + /* Initialize reblocking logic. */ + a->buffer_size = 64 * 1024; /* 64k */ + a->buffer = (char *)malloc(a->buffer_size); + a->next = a->buffer; + if (a->buffer == NULL) { + archive_entry_free(a->entry); + free(a); + return (NULL); + } return (&a->archive); } @@ -108,6 +116,33 @@ client_reader, NULL, client_closer); } +static ssize_t +client_read_proxy(struct archive_read_source *self, const void **buff) +{ + return (self->archive->client.reader)((struct archive *)self->archive, + self->data, buff); +} + +static int64_t +client_skip_proxy(struct archive_read_source *self, int64_t request) +{ + return (self->archive->client.skipper)((struct archive *)self->archive, + self->data, request); +} + +static int +client_close_proxy(struct archive_read_source *self) +{ + int r = ARCHIVE_OK; + + if (self->archive->client.closer != NULL) + r = (self->archive->client.closer)((struct archive *)self->archive, + self->data); + free(self); + return (r); +} + + int archive_read_open2(struct archive *_a, void *client_data, archive_open_callback *client_opener, @@ -116,28 +151,15 @@ archive_close_callback *client_closer) { struct archive_read *a = (struct archive_read *)_a; - const void *buffer; - ssize_t bytes_read; int e; - __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, "archive_read_open"); + __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, + "archive_read_open"); if (client_reader == NULL) __archive_errx(1, "No reader function provided to archive_read_open"); - /* - * Set these NULL initially. If the open or initial read fails, - * we'll leave them NULL to indicate that the file is invalid. - * (In particular, this helps ensure that the closer doesn't - * get called more than once.) - */ - a->client_opener = NULL; - a->client_reader = NULL; - a->client_skipper = NULL; - a->client_closer = NULL; - a->client_data = NULL; - /* Open data source. */ if (client_opener != NULL) { e =(client_opener)(&a->archive, client_data); @@ -149,129 +171,103 @@ } } - /* Read first block now for compress format detection. */ - bytes_read = (client_reader)(&a->archive, client_data, &buffer); + /* Save the client functions and mock up the initial source. */ + a->client.opener = client_opener; /* Do we need to remember this? */ + a->client.reader = client_reader; + a->client.skipper = client_skipper; + a->client.closer = client_closer; + a->client.data = client_data; + + { + struct archive_read_source *source; - if (bytes_read < 0) { - /* If the first read fails, close before returning error. */ - if (client_closer) - (client_closer)(&a->archive, client_data); - /* client_reader should have already set error information. */ - return (ARCHIVE_FATAL); + source = calloc(1, sizeof(*source)); + if (source == NULL) + return (ARCHIVE_FATAL); + source->reader = NULL; + source->upstream = NULL; + source->archive = a; + source->data = client_data; + source->read = client_read_proxy; + source->skip = client_skip_proxy; + source->close = client_close_proxy; + a->source = source; } - /* Now that the client callbacks have worked, remember them. */ - a->client_opener = client_opener; /* Do we need to remember this? */ - a->client_reader = client_reader; - a->client_skipper = client_skipper; - a->client_closer = client_closer; - a->client_data = client_data; + /* In case there's no filter. */ + a->archive.compression_code = ARCHIVE_COMPRESSION_NONE; + a->archive.compression_name = "none"; - /* Select a decompression routine. */ - choose_decompressor(a, buffer, (size_t)bytes_read); - if (a->decompressor == NULL) - return (ARCHIVE_FATAL); - - /* Initialize decompression routine with the first block of data. */ - e = (a->decompressor->init)(a, buffer, (size_t)bytes_read); - + /* Build out the input pipeline. */ + e = build_stream(a); if (e == ARCHIVE_OK) a->archive.state = ARCHIVE_STATE_HEADER; - /* - * If the decompressor didn't register a skip function, provide a - * dummy compression-layer skip function. - */ - if (a->decompressor->skip == NULL) - a->decompressor->skip = dummy_skip; - return (e); } /* - * Allow each registered decompression routine to bid on whether it - * wants to handle this stream. Return index of winning bidder. + * Allow each registered stream transform to bid on whether + * it wants to handle this stream. Repeat until we've finished + * building the pipeline. */ -static void -choose_decompressor(struct archive_read *a, - const void *buffer, size_t bytes_read) +static int +build_stream(struct archive_read *a) { - int decompression_slots, i, bid, best_bid; - struct decompressor_t *decompressor, *best_decompressor; + int number_readers, i, bid, best_bid; + struct archive_reader *reader, *best_reader; + struct archive_read_source *source; + const void *block; + ssize_t bytes_read; + + /* Read first block now for compress format detection. */ + bytes_read = (a->source->read)(a->source, &block); + if (bytes_read < 0) { + /* If the first read fails, close before returning error. */ + if (a->source->close != NULL) { + (a->source->close)(a->source); + a->source = NULL; + } + /* source->read should have already set error information. */ + return (ARCHIVE_FATAL); + } - decompression_slots = sizeof(a->decompressors) / - sizeof(a->decompressors[0]); + number_readers = sizeof(a->readers) / sizeof(a->readers[0]); best_bid = 0; - a->decompressor = NULL; - best_decompressor = NULL; + best_reader = NULL; - decompressor = a->decompressors; - for (i = 0; i < decompression_slots; i++) { - if (decompressor->bid) { - bid = (decompressor->bid)(buffer, bytes_read); - if (bid > best_bid || best_decompressor == NULL) { + reader = a->readers; + for (i = 0, reader = a->readers; i < number_readers; i++, reader++) { + if (reader->bid != NULL) { + bid = (reader->bid)(reader, block, bytes_read); + if (bid > best_bid) { best_bid = bid; - best_decompressor = decompressor; + best_reader = reader; } } - decompressor ++; } /* - * There were no bidders; this is a serious programmer error - * and demands a quick and definitive abort. + * If we have a winner, it becomes the next stage in the pipeline. */ - if (best_decompressor == NULL) - __archive_errx(1, "No decompressors were registered; you " - "must call at least one " - "archive_read_support_compression_XXX function in order " - "to successfully read an archive."); - - /* - * There were bidders, but no non-zero bids; this means we can't - * support this stream. - */ - if (best_bid < 1) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unrecognized archive format"); - return; - } - - /* Record the best decompressor for this stream. */ - a->decompressor = best_decompressor; -} - -/* - * Dummy skip function, for use if the compression layer doesn't provide - * one: This code just reads data and discards it. - */ -static off_t -dummy_skip(struct archive_read * a, off_t request) -{ - const void * dummy_buffer; - ssize_t bytes_read; - off_t bytes_skipped; - - for (bytes_skipped = 0; request > 0;) { - bytes_read = (a->decompressor->read_ahead)(a, &dummy_buffer, 1); - if (bytes_read < 0) - return (bytes_read); - if (bytes_read == 0) { - /* Premature EOF. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated input file (need to skip %jd bytes)", - (intmax_t)request); + if (best_reader != NULL) { + source = (best_reader->init)(a, best_reader, a->source, + block, bytes_read); + if (source == NULL) return (ARCHIVE_FATAL); - } - if (bytes_read > request) - bytes_read = (ssize_t)request; - (a->decompressor->consume)(a, (size_t)bytes_read); - request -= bytes_read; - bytes_skipped += bytes_read; + /* Record the best decompressor for this stream. */ + a->source = source; + /* Recurse to get next pipeline stage. */ + return (build_stream(a)); } - return (bytes_skipped); + /* Save first block of data. */ + a->client_buff = block; + a->client_total = bytes_read; + a->client_next = a->client_buff; + a->client_avail = a->client_total; + return (ARCHIVE_OK); } /* @@ -598,23 +594,24 @@ /* TODO: Clean up the formatters. */ - /* Clean up the decompressors. */ - n = sizeof(a->decompressors)/sizeof(a->decompressors[0]); + /* Clean up the stream pipeline. */ + if (a->source != NULL) { + r1 = (a->source->close)(a->source); + if (r1 < r) + r = r1; + a->source = NULL; + } + + /* Release the reader objects. */ + n = sizeof(a->readers)/sizeof(a->readers[0]); for (i = 0; i < n; i++) { - if (a->decompressors[i].finish != NULL) { - r1 = (a->decompressors[i].finish)(a); + if (a->readers[i].free != NULL) { + r1 = (a->readers[i].free)(&a->readers[i]); if (r1 < r) r = r1; } } - /* Close the client stream. */ - if (a->client_closer != NULL) { - r1 = ((a->client_closer)(&a->archive, a->client_data)); - if (r1 < r) - r = r1; - } - return (r); } @@ -651,6 +648,7 @@ if (a->entry) archive_entry_free(a->entry); a->archive.magic = 0; + free(a->buffer); free(a); #if ARCHIVE_API_VERSION > 1 return (r); @@ -700,40 +698,350 @@ * Used internally by decompression routines to register their bid and * initialization functions. */ -struct decompressor_t * -__archive_read_register_compression(struct archive_read *a, - int (*bid)(const void *, size_t), - int (*init)(struct archive_read *, const void *, size_t)) +struct archive_reader * +__archive_read_get_reader(struct archive_read *a) { int i, number_slots; __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "__archive_read_register_compression"); + "__archive_read_get_reader"); - number_slots = sizeof(a->decompressors) / sizeof(a->decompressors[0]); + number_slots = sizeof(a->readers) / sizeof(a->readers[0]); for (i = 0; i < number_slots; i++) { - if (a->decompressors[i].bid == bid) - return (a->decompressors + i); - if (a->decompressors[i].bid == NULL) { - a->decompressors[i].bid = bid; - a->decompressors[i].init = init; - return (a->decompressors + i); - } + if (a->readers[i].bid == NULL) + return (a->readers + i); } __archive_errx(1, "Not enough slots for compression registration"); return (NULL); /* Never actually executed. */ } -/* used internally to simplify read-ahead */ +/* + * The next three functions comprise the peek/consume internal I/O + * system used by archive format readers. This system allows fairly + * flexible read-ahead and allows the I/O code to operate in a + * zero-copy manner most of the time. + * + * In the ideal case, block providers give the I/O code blocks of data + * and __archive_read_ahead() just returns pointers directly into + * those blocks. Then __archive_read_consume() just bumps those + * pointers. Only if your request would span blocks does the I/O + * layer use a copy buffer to provide you with a contiguous block of + * data. The __archive_read_skip() is an optimization; it scans ahead + * very quickly (it usually translates into a seek() operation if + * you're reading uncompressed disk files). + * + * A couple of useful idioms: + * * "I just want some data." Ask for 1 byte and pay attention to + * the "number of bytes available" from __archive_read_ahead(). + * You can consume more than you asked for; you just can't consume + * more than is available right now. If you consume everything that's + * immediately available, the next read_ahead() call will pull + * the next block. + * * "I want to output a large block of data." As above, ask for 1 byte, + * emit all that's available (up to whatever limit you have), then + * repeat until you're done. + * * "I want to peek ahead by a large amount." Ask for 4k or so, then + * double and repeat until you get an error or have enough. Note + * that the I/O layer will likely end up expanding its copy buffer + * to fit your request, so use this technique cautiously. This + * technique is used, for example, by some of the format tasting + * code that has uncertain look-ahead needs. + * + * TODO: Someday, provide a more generic __archive_read_seek() for + * those cases where it's useful. This is tricky because there are lots + * of cases where seek() is not available (reading gzip data from a + * network socket, for instance), so there needs to be a good way to + * communicate whether seek() is available and users of that interface + * need to use non-seeking strategies whenever seek() is not available. + */ + +/* + * Looks ahead in the input stream: + * * If 'avail' pointer is provided, that returns number of bytes available + * in the current buffer, which may be much larger than requested. + * * If end-of-file, *avail gets set to zero. + * * If error, *avail gets error code. + * * If request can be met, returns pointer to data, returns NULL + * if request is not met. + * + * Note: If you just want "some data", ask for 1 byte and pay attention + * to *avail, which will have the actual amount available. If you + * know exactly how many bytes you need, just ask for that and treat + * a NULL return as an error. + * + * Important: This does NOT move the file pointer. See + * __archive_read_consume() below. + */ + +/* + * This is tricky. We need to provide our clients with pointers to + * contiguous blocks of memory but we want to avoid copying whenever + * possible. + * + * Mostly, this code returns pointers directly into the block of data + * provided by the client_read routine. It can do this unless the + * request would split across blocks. In that case, we have to copy + * into an internal buffer to combine reads. + */ const void * -__archive_read_ahead(struct archive_read *a, size_t len) +__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) { - const void *h; + ssize_t bytes_read; + size_t tocopy; - if ((a->decompressor->read_ahead)(a, &h, len) < (ssize_t)len) + if (a->fatal) { + if (avail) + *avail = ARCHIVE_FATAL; return (NULL); - return (h); + } + + /* + * Keep pulling more data until we can satisfy the request. + */ + for (;;) { + + /* + * If we can satisfy from the copy buffer, we're done. + */ + if (a->avail >= min) { + if (avail != NULL) + *avail = a->avail; + return (a->next); + } + + /* + * We can satisfy directly from client buffer if everything + * currently in the copy buffer is still in the client buffer. + */ + if (a->client_total >= a->client_avail + a->avail + && a->client_avail + a->avail >= min) { + /* "Roll back" to client buffer. */ + a->client_avail += a->avail; + a->client_next -= a->avail; + /* Copy buffer is now empty. */ + a->avail = 0; + a->next = a->buffer; + /* Return data from client buffer. */ + if (avail != NULL) + *avail = a->client_avail; + return (a->client_next); + } + + /* Move data forward in copy buffer if necessary. */ + if (a->next > a->buffer && + a->next + min > a->buffer + a->buffer_size) { + if (a->avail > 0) + memmove(a->buffer, a->next, a->avail); + a->next = a->buffer; + } + + /* If we've used up the client data, get more. */ + if (a->client_avail <= 0) { + if (a->end_of_file) { + if (avail != NULL) + *avail = 0; + return (NULL); + } + bytes_read = (a->source->read)(a->source, + &a->client_buff); + if (bytes_read < 0) { /* Read error. */ + a->client_total = a->client_avail = 0; + a->client_next = a->client_buff = NULL; + a->fatal = 1; + if (avail != NULL) + *avail = ARCHIVE_FATAL; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812071206.mB7C65DK060769>