From dac0f3cb8b9cd374295ab9c814ee4f9d72a1293b Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 26 Sep 2010 21:16:08 +0200 Subject: No more useless seek (as far I know) --- pdftool.pl | 119 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 41 deletions(-) diff --git a/pdftool.pl b/pdftool.pl index bb4d3dc..5c331ce 100755 --- a/pdftool.pl +++ b/pdftool.pl @@ -72,6 +72,9 @@ Version: 0.1, 25 September 2010 =cut +# TODO: inline it in the header +$main::VERSION = "0.1, 25 September 2010"; + my $tmpdir = '/tmp'; @@ -155,6 +158,9 @@ if (defined $infile && $infile ne "-") { *FIN = *STDIN; $infile_display = "(stdin)"; } +# After the pipe, it won't be detected as seekable +my $inseek = (seek FIN, 0, 1) ? 1 : undef; + if (defined $outfile && $outfile ne "-") { open FOUT, '>', "$outfile" or die "Can't create `$outfile': $!"; @@ -167,15 +173,42 @@ if (defined $outfile && $outfile ne "-") { # # Detect filetype # +# To avoid to seek into FIN, it gonna be copied from WRITE to READ in +# background, once the filetype has been read + +# TODO: read specification to detect filetype properly my $filetype; -my $fstline = ; -if (defined $fstline && $fstline =~ /^%!PS.*/) { - $filetype = "PS"; -} elsif (defined $fstline && $fstline =~ /^%PDF.*/) { - $filetype = "PDF"; -} else { - die "Can't recognize the type of `$infile_display'"; +pipe *READ, *WRITE or die "Can't pipe: $!"; +while (not (defined $filetype) && defined (my $l = )) { + print WRITE $l or die "Can't close: $!"; + + if (defined $l && $l =~ /^%!PS/) { + $filetype = "PS"; + } elsif (defined $l && $l =~ /^%PDF/) { + $filetype = "PDF"; + } +} + +die "Cannot recognise FileType" unless defined $filetype; + +unless (my $pid = fork) { + # Child: cat FIN > WRITE in background + die "Can't fork: $!" unless defined $pid; + close READ or die "Can't close: $!"; + + while () { + print WRITE or die "Can't print: $!"; + } + exit; } +# Parent + +close WRITE or die "Can't close: $!"; +close FIN or die "Can't close: $!"; + +open *FIN, "<&READ" or die "Can't dup: $!"; + + # Auxiliary files, to remove my @auxfiles; @@ -185,7 +218,6 @@ my @auxfds; # Pids, to waid for my @pids; -my $pid; @@ -194,39 +226,37 @@ my $pid; # my @cmd; if ($filetype eq "PDF") { - unless (defined $infile) { + unless (defined $infile && $inseek) { # Need to copy the whole input to an auxiliary file, since # conversion from PDF to PS requires random access to the data $infile = "$tmpdir/pdftool-stdin-$$" . lc ".$filetype"; - open FIN2, '>', "$infile" + open FINAUX, '>', "$infile" or die "Can't write into `$infile': $!"; push @auxfiles, "$infile"; - # cat > $filename - # TODO: useless seek - seek FIN, 0, 0 or die $!; + # cat > $infile while () { - print FIN2 $_ or die "Can't print: $!"; + print FINAUX or die "Can't print: $!"; } - close FIN2; + close FINAUX; } - close FIN; + # Convert to PS @cmd = ('pdftops', "$infile", '-'); push @cmd, '-q' if defined $quiet; - $pid = open *PSIN, "-|", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - push @pids, $pid; + my $pid = open PSIN, "-|", @cmd + or die "Can't run `" . &printcmd (@cmd) . "'"; + my @pair = ($pid, @cmd); + push @pids, \@pair; } else { - # TODO: useless seek - seek FIN, 0, 0 or die $!; *PSIN = *FIN; } + # # Select, if necessary # @@ -234,9 +264,9 @@ if ($filetype eq "PDF") { if (defined $select) { @cmd = ('psselect', "-p$select"); push @cmd, '-q' if defined $quiet; - $pid = open2 *PSSELECT, "<&PSIN", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - push @pids, $pid; + my $pid = open2 *PSSELECT, "<&PSIN", @cmd; + my @pair = ($pid, @cmd); + push @pids, \@pair; } else { *PSSELECT = *PSIN; } @@ -250,9 +280,9 @@ if (defined $select) { push @cmd, "-c" if defined $crop; push @cmd, '-q' if defined $quiet; -$pid = open2 *PSRESIZE, "<&PSSELECT", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; -push @pids, $pid; +my $pid = open2 *PSRESIZE, "<&PSSELECT", @cmd; +my @pair = ($pid, @cmd); +push @pids, \@pair; # Note: open2 closes the filehandles for us :) @@ -263,9 +293,10 @@ push @pids, $pid; if (defined $book) { @cmd = ('psbook'); push @cmd, '-q' if defined $quiet; - $pid = open2 *PSBOOK, "<&PSRESIZE", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - push @pids, $pid; + + my $pid = open2 *PSBOOK, "<&PSRESIZE", @cmd; + my @pair = ($pid, @cmd); + push @pids, \@pair; } else { *PSBOOK = *PSRESIZE; } @@ -278,9 +309,10 @@ if (defined $book) { if ($nup > 1) { @cmd = ('psnup', "-p$paper", "-m$mnup", "-$nup"); push @cmd, '-q' if defined $quiet; - $pid = open2 *PSOUT, "<&PSBOOK", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - push @pids, $pid; + + my $pid = open2 *PSOUT, "<&PSBOOK", @cmd; + my @pair = ($pid, @cmd); + push @pids, \@pair; } else { *PSOUT = *PSBOOK; } @@ -294,25 +326,30 @@ if ($filetype eq "PDF") { # Convert back to PDF @cmd = ('ps2pdf', "-dEmbedAllFonts=true", "-sPAPERSIZE=$paper", '-', '-'); - $pid = open2 ">&FOUT", "<&PSOUT", @cmd - or die "Can't run: `" . &printcmd (@cmd) . "'"; - push @pids, $pid; + $pid = open2 ">&FOUT", "<&PSOUT", @cmd; + my @pair = ($pid, @cmd); + push @pids, \@pair; } else { # cat > FOUT while () { - print FOUT $_ or die "Can't print: $!"; + print FOUT or die "Can't print: $!"; } } # Avoid zombies -map {waitpid $_, 0} @pids; +map { my ($pid, @cmd) = @$_; +# print STDERR "PID: ", $pid, " Cmd: `", &printcmd (@cmd), "'"; + my ($r,$v) = (waitpid ($pid, 0), $?); + warn "Can't run `" . &printcmd (@cmd) . "'" if ($r != -1 and $v >> 8); + } @pids; # Close auxiliary filehandles -map {close $_} @auxfds; -close FIN; -close FOUT; +map {close} @auxfds; +close READ or die "Can't close: $!"; +close FIN or die "Can't close: $!"; +close FOUT or die "Can't close: $!"; # Delete auxiliary files -- cgit v1.2.3