diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2004-12-11 14:05:14 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2004-12-11 14:05:14 +0000 |
commit | c8f9f8f01b0474052b6abaaa267102e80576ce9d (patch) | |
tree | 3ba160990ac983188b053bfac7af469f4fa1987b /usr.sbin/pkg_add/OpenBSD/Ustar.pm | |
parent | c385ba7c13c5d6c66464a0dafe0ff06780709d43 (diff) |
implement zeroes blocks detection
Diffstat (limited to 'usr.sbin/pkg_add/OpenBSD/Ustar.pm')
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Ustar.pm | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Ustar.pm b/usr.sbin/pkg_add/OpenBSD/Ustar.pm index 1dc73f4f22c..ab56ceef598 100644 --- a/usr.sbin/pkg_add/OpenBSD/Ustar.pm +++ b/usr.sbin/pkg_add/OpenBSD/Ustar.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Ustar.pm,v 1.12 2004/11/01 15:44:11 espie Exp $ +# $OpenBSD: Ustar.pm,v 1.13 2004/12/11 14:05:13 espie Exp $ # # Copyright (c) 2002-2004 Marc Espie <espie@openbsd.org> # @@ -37,6 +37,8 @@ use OpenBSD::IdCache; my $uidcache = new OpenBSD::UidCache; my $gidcache = new OpenBSD::GidCache; + +# This is a multiple of st_blksize everywhere.... my $buffsize = 2 * 1024 * 1024; sub new @@ -207,6 +209,36 @@ sub isSymLink() { 1 } package OpenBSD::Ustar::File; our @ISA=qw(OpenBSD::Ustar::Object); +my $bs; +my $zeroes; +sub print_compact +{ + my ($fh, $buffer) = @_; + my $newbs = (stat $fh)[11]; + if (!defined $bs or $newbs != $bs) { + $bs = $newbs; + $zeroes = "\x00"x$bs; + } +START: + if (defined $bs) { + for (my $i = 0; $i + $bs <= length($buffer); $i+= $bs) { + if (substr($buffer, $i, $bs) eq $zeroes) { + syswrite($fh, $buffer, $i) or return 0; + $i+=$bs; + my $seek_forward = $bs; + while (substr($buffer, $i, $bs) eq $zeroes) { + $i += $bs; + $seek_forward += $bs; + } + sysseek($fh, $seek_forward, 1) or return 0; + $buffer = substr($buffer, $i); + goto START; + } + } + } + syswrite($fh, $buffer) or return 0; +} + sub create { my $self = shift; @@ -224,7 +256,7 @@ sub create die "Error reading from archive: $!"; } $self->{archive}->{swallow} -= $maxread; - unless (print $out $buffer) { + unless (print_compact($out, $buffer)) { die "Error writing to $self->{destdir}$self->{name}: $!"; } |