sub truncate_front { my $fh = shift; my $pos = shift; my $length = (stat ($fh))[7]; my $buf; my $buf_size = ($pos < 1024 ? $pos : 1024); my $status; if ($pos <= 0) { return ($length); } elsif ($pos >= $length) { truncate ($fh, 0) or die ('truncate: ' . $!); return (0); } $length = 0; while (1) { my $read_pos = $pos + $length; seek ($fh, $read_pos, 0) or die ('seek: ' . $!); $status = read ($fh, $buf, $buf_size); if (!defined ($status)) { die ('read: ' . $!); } elsif ($status == 0) { last; } seek ($fh, $length, 0) or die ('seek: ' . $!); print $fh $buf; $length += $status; } if (defined ($status)) { truncate ($fh, $length) or die ('truncate: ' . $!); } return ($length); }