summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts')
-rwxr-xr-xMaster/texmf-dist/scripts/latexmk/latexmk.pl312
1 files changed, 245 insertions, 67 deletions
diff --git a/Master/texmf-dist/scripts/latexmk/latexmk.pl b/Master/texmf-dist/scripts/latexmk/latexmk.pl
index b5e5fe77ff5..b03c9a58da6 100755
--- a/Master/texmf-dist/scripts/latexmk/latexmk.pl
+++ b/Master/texmf-dist/scripts/latexmk/latexmk.pl
@@ -24,7 +24,6 @@ use warnings;
#=======================================
-
#?? Force mode doesn't appear to do force (if error in latex file)
#??? Get banner back in.
#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE
@@ -33,7 +32,7 @@ use warnings;
#?? logfile w/o fdb file: don't set changed file, perhaps for generated exts.
# Reconsider
#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think
-# Parse and correctly find bst and ist files
+# Parse and correctly find ist files
# ATTEMPT TO ALLOW FILENAMES WITH SPACES:
@@ -108,8 +107,8 @@ use warnings;
$my_name = 'latexmk';
$My_name = 'Latexmk';
-$version_num = '4.18';
-$version_details = "$My_name, John Collins, 27 July 2010";
+$version_num = '4.21';
+$version_details = "$My_name, John Collins, 28 December 2010";
use Config;
@@ -178,6 +177,41 @@ else {
##
## Modification log from 23 Jun 2010 onwards in detail
##
+## 28 Dec 2010, John Collins Version number to 4.21
+## 1. Improved handling of quotes in filenames in log file:
+## a. Clean double quotes in names from messages about files.
+## b. In ("..." construct, as in MiKTeX, the only character
+## prohibited is ". Previously I disallowed ( and ),
+## which are allowed special characters.
+## 2. Reversed deletion and reinsertion in dependents list
+## of name found by kpsewhich. Otherwise sometimes a name
+## could be deleted in error
+## 12 Nov 2010, John Collins Version number to 4.20
+## 11 Nov 2010, John Collins Fix problem that when bibtex finds no
+## citations, this is treated by bibtex as an
+## error, but latexmk should only treat it as
+## a warning but not an error
+## 8,9 Nov 2010, John Collins Get .bst file in source file list for bibtex
+## 30 Oct 2010, John Collins Allow clean-up to delete destination files of
+## custom-dependencies
+## Configuration variable $cleanup_includes_cusdep_generated to
+## whether this is done
+## 20 Sep 2010, John Collins First attempt to deal with no citations warning
+## Still have the problem that bibtex gives non-zero exit code
+## 19 Sep 2010, John Collins Orthogonalize option and command specification
+## a la Manuel Pegourie-Gonnard (email of 19 Sep 2010,
+## "[latexmk] latex engine and default options".)
+## Still needs documentation.
+## 19 Sep 2010, John Collins More general pattern for files to clean up,
+## Thanks to Manuel Pegourie-Gonnard for the code
+## Must check the use of %generated_exts_all in
+## sub rdb_file_change1.
+## 30 Aug 2010, John Collins Remove double quotes (if any) surrounding
+## output filename read from .log file.
+## (Avoids wrong diagnostic message.)
+## 19 Aug 2010, John Collins Remove use of --width option on $pscmd
+## on linux. It's no longer needed.
+## 30 Jul 2010, John Collins Timing information
## 27 Jul 2010, John Collins Clean up some comments.
## This is release version for 4.18.
## 23 Jul 2010, John Collins Only produce "Removing no-longer-needed
@@ -332,6 +366,11 @@ $log_wrap = 79;
## Commands to invoke latex, pdflatex
$latex = 'latex %O %S';
$pdflatex = 'pdflatex %O %S';
+
+## Default switches:
+$latex_default_switches = '';
+$pdflatex_default_switches = '';
+
## Switch(es) to make them silent:
$latex_silent_switch = '-interaction=batchmode';
$pdflatex_silent_switch = '-interaction=batchmode';
@@ -727,7 +766,10 @@ else {
# for SUSE 7.2).
# However the option is not available under other UNIX-type
# systems, e.g., Solaris 8.
- $pscmd = "ps --width 200 -f -u $ENV{USER}";
+ # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5,
+ # unless the output is written to a terminal. So the --width
+ # option is now unnecessary
+ # $pscmd = "ps --width 200 -f -u $ENV{USER}";
}
elsif ( $^O eq "darwin" ) {
# OS-X on Macintosh
@@ -849,6 +891,9 @@ $cleanup_fdb = 0; # No removal of file for latexmk's file-database
$cleanup_only = 0; # When doing cleanup, do not go-on to making files
$cleanup_includes_generated = 0;
# Determines whether cleanup deletes files generated by
+ # custom dependencies
+$cleanup_includes_cusdep_generated = 0;
+ # Determines whether cleanup deletes files generated by
# (pdf)latex (found from \openout lines in log file).
$diagnostics = 0;
$dvi_filter = ''; # DVI filter command
@@ -861,6 +906,11 @@ $preview_mode = 0;
$preview_continuous_mode = 0;
$printout_mode = 0; # Don't print the file
+$show_time = 0;
+@timings = ();
+$processing_time1 = processing_time();
+
+
# Do we make view file in temporary then move to final destination?
# (To avoid premature updating by viewer).
$always_view_file_via_temporary = 0; # Set to 1 if viewed file is always
@@ -1210,6 +1260,12 @@ while ($_ = $ARGV[0])
}
elsif (/^-l$/) { $landscape_mode = 1; }
elsif (/^-l-$/) { $landscape_mode = 0; }
+ elsif (/^-latex=(.*)$/) {
+ $latex = $1;
+ }
+ elsif (/^-pdflatex=(.*)$/) {
+ $pdflatex = $1;
+ }
elsif (/^-new-viewer$/) {
$new_viewer_always = 1;
}
@@ -1249,6 +1305,8 @@ while ($_ = $ARGV[0])
}
elsif (/^-pvc-$/) { $preview_continuous_mode = 0; }
elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; }
+ elsif (/^-time$/) { $show_time = 1;}
+ elsif (/^-time-$/) { $show_time = 0;}
elsif (/^-v$/ || /^-version$/) {
print "\n$version_details. Version $version_num\n";
exit;
@@ -1453,6 +1511,11 @@ if ( ($jobname ne '') && ($num_files > 1) ) {
# Normalize the commands, to have place-holders for source, dest etc:
&fix_cmds;
+# Add common options
+add_option( \$latex, $latex_default_switches );
+add_option( \$pdflatex, $pdflatex_default_switches );
+
+
# If landscape mode, change dvips processor, and the previewers:
if ( $landscape_mode )
{
@@ -1618,9 +1681,17 @@ foreach $filename ( @file_list )
local %conversions = (); # (pdf)latex-performed conversions.
# Maps output file created and read by (pdf)latex
# to source file of conversion.
+
print "$My_name: Examining log file for generated files...\n";
&parse_logB;
+ print "$My_name: Examining fdb file for rules ...\n";
+ # Needed for cleanup of files generated by custom dependencies
+ if ( -e $fdb_file ) {
+ $rdb_errors = rdb_read( $fdb_file );
+ $have_fdb = ($rdb_errors == 0);
+ }
+
my @index_bibtex_generated = ();
my @aux_files = ();
my %other_generated = %generated_log;
@@ -1665,6 +1736,9 @@ foreach $filename ( @file_list )
if ($cleanup_includes_generated) {
unlink( keys %other_generated );
}
+ if ( $cleanup_includes_cusdep_generated) {
+ &cleanup_cusdep_generated;
+ }
if ( $cleanup_mode == 1 ) {
&cleanup1( 'dvi', 'dviF', 'ps', 'psF', 'pdf',
split(' ', $clean_full_ext)
@@ -1796,6 +1870,16 @@ continue {
}
&ifcd_popd;
}
+
+if ($show_time) { show_timing();}
+
+sub show_timing {
+ my $processing_time = processing_time() - $processing_time1;
+ print @timings, "Accumulated processing time = $processing_time\n";
+ @timings = ();
+ $processing_time1 = processing_time();
+}
+
# If we get here without going through the continue section:
if ( $do_cd && ($#dir_stack > -1) ) {
# Just in case we did an abnormal exit from the loop
@@ -2403,6 +2487,7 @@ CHANGE:
" ==> You will need to change a source file before I do another run <==\n";
}
rdb_show_rule_errors();
+ if ($show_time && ! $first_time) { show_timing(); }
if ( $first_time || $updated || $failure ) {
print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
}
@@ -2419,6 +2504,8 @@ CHANGE:
}
last WAIT;
}
+ # Don't count waiting time in processing:
+ $processing_time1 = processing_time();
# Does this do this job????
local $new_files = 0;
rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_filesB } );
@@ -2521,10 +2608,42 @@ sub execute_code_string {
sub cleanup1 {
# Usage: cleanup1( exts_without_period, ... )
- foreach (@_) { unlink("$root_filename.$_"); }
+ foreach (@_) {
+ (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/$root_filename/;
+ unlink("$name");
+ }
} #END cleanup1
#************************************************************
+
+sub cleanup_cusdep_generated {
+ # Remove files generated by custom dependencies
+ rdb_for_all( \&cleanup_one_cusdep_generated );
+} #END cleanup_cusdep_generated
+
+#************************************************************
+
+sub cleanup_one_cusdep_generated {
+ # Remove destination file generated by one custom dependency
+ # Assume rule context, but not that the rule is a custom dependency.
+ # Only delete destination file if source file exists (so destination
+ # file can be recreated)
+ if ( $$Pcmd_type ne 'cusdep' ) {
+ # NOT cusdep
+ return;
+ }
+ if ( (-e $$Pdest) && (-e $$Psource) ) {
+ unlink $$Pdest;
+ }
+ elsif ( (-e $$Pdest) && (!-e $$Psource) ) {
+ warn "$My_name: For custom dependency '$rule',\n",
+ " I won't delete destination file '$$Pdest'\n",
+ " because the source file '$$Psource' doesn't exist,\n",
+ " so the destination file may not be able to be recreated\n";
+ }
+} #END cleanup_one_cusdep_generated
+
+#************************************************************
#************************************************************
#************************************************************
@@ -2644,12 +2763,16 @@ sub print_help
" implementations of latex/pdflatex.)\n",
" -l - force landscape mode\n",
" -l- - turn off -l\n",
+ " -latex=<program> - set program used for latex.\n",
+ " (replace '<program>' by the program name)\n",
" -new-viewer - in -pvc mode, always start a new viewer\n",
" -new-viewer- - in -pvc mode, start a new viewer only if needed\n",
" -nobibtex - never use bibtex\n",
" -nodependents - Do not show list of dependent files after processing\n",
" -pdf - generate pdf by pdflatex\n",
" -pdfdvi - generate pdf by dvipdf\n",
+ " -pdflatex=<program> - set program used for pdflatex.\n",
+ " (replace '<program>' by the program name)\n",
" -pdfps - generate pdf by ps2pdf\n",
" -pdf- - turn off pdf\n",
" -ps - generate postscript\n",
@@ -2668,7 +2791,9 @@ sub print_help
" -pvc- - turn off -pvc\n",
" -r <file> - Read custom RC file\n",
" -silent - silence progress messages from called programs\n",
- " -v - display program version\n",
+ " -time - show CPU time used\n",
+ " -time- - don't show CPU time used\n",
+ " -v - display program version\n",
" -verbose - display usual progress messages from called programs\n",
" -version - display program version\n",
" -view=default - viewer is default (dvi, ps, pdf)\n",
@@ -2730,12 +2855,14 @@ sub view_file_via_temporary {
#************************************************************
#### Tex-related utilities
+#**************************************************
sub check_bibtex_log {
# Check for bibtex warnings:
# Usage: check_bibtex_log( base_of_bibtex_run )
# return 0: OK, 1: bibtex warnings, 2: bibtex errors,
# 3: could not open .blg file.
+ # 10: only error is missing \citation commands.
my $base = $_[0];
my $log_name = "$base.blg";
@@ -2744,17 +2871,35 @@ sub check_bibtex_log {
or return 3;
my $have_warning = 0;
my $have_error = 0;
+ my $missing_citations = 0;
+ my $error_count = 0;
while (<$log_file>) {
- if (/Warning--/) {
+ if (/^Warning--/) {
#print "Bibtex warning: $_";
$have_warning = 1;
}
- if (/error message/) {
- #print "Bibtex error: $_";
+ elsif ( /^I found no \\citation commands---while reading file/ ) {
+ $missing_citations++;
+ }
+ elsif (/There (were|was) (\d+) error message/) {
+ $error_count = $2;
+ #print "Bibtex error: count=$error_count $_";
$have_error = 1;
}
}
close $log_file;
+ #print "Bibtex errors = $error_count, missing citations = $missing_citations\n";
+ if ($have_error && ($error_count <= $missing_citations )
+ && ($missing_citations > 0) ) {
+ # If the only error is a missing citation line, that should only
+ # count as a warning.
+ # But have to deal with the problem that bibtex gives a non-zero
+ # exit code. So leave things as they are so that the user gets
+ # a better diagnostic ??????????????????????????
+# $have_error = 0;
+# $have_warning = 1;
+ return 10;
+ }
if ($have_error) {return 2;}
if ($have_warning) {return 1;}
return 0;
@@ -2762,18 +2907,23 @@ sub check_bibtex_log {
#**************************************************
-sub clean_file_name{
- # Convert filename found in log file to true filename.
- # Used normally only by parse_logB, below
- # 1. For names of form
- # `"string".ext', which arises e.g., from \jobname.bbl:
+sub clean_file_name {
+ # Convert quoted filename as found in log file to filename without quotes
+ # Allows arbitrarily embedded double-quoted substrings, includes the
+ # cases
+ # 1. `"string".ext', which arises e.g., from \jobname.bbl:
# when the base filename contains spaces, \jobname has quotes.
# and from \includegraphics with basename specified.
+ # Also deals with filenames written by asymptote.sty
# 2. Or "string.ext" from \includegraphcs with basename and ext specified.
+ # and from MiKTeX logfile for input files with spaces.
+ # Doubled quotes (e.g., A""B) don't get converted.
+ # Neither do unmatched quotes.
my $filename = $_[0];
- $filename =~ s/^\"([^\"]*)\"(.*)$/$1$2/;
+ while ( $filename =~ s/^([^\"]*)\"([^\"]+)\"(.*)$/$1$2$3/ ) {}
return $filename;
}
+
# ------------------------------
sub parse_logB {
@@ -2973,8 +3123,8 @@ LINE:
next LINE;
}
if ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
- $primary_out = $1;
- warn "$My_name: Log file says output to '$1'\n"
+ $primary_out = clean_file_name($1);
+ warn "$My_name: Log file says output to '$primary_out'\n"
unless $silent;
next LINE;
}
@@ -2987,15 +3137,15 @@ LINE:
next LINE;
}
if ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
- $generated_log{$1} = 1;
+ $generated_log{clean_file_name($1)} = 1;
next LINE;
}
# Test for conversion produced by package:
if ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
# Info. produced by epstopdf (and possibly others)
# about file conversion
- $current_pkg = $1;
- $delegated_source = $2;
+ $current_pkg = clean_file_name($1);
+ $delegated_source = clean_file_name($2);
$block_type = 'conversion';
next LINE;
}
@@ -3064,9 +3214,9 @@ LINE:
next LINE;
}
}
- if ( /^File: ([^\s\[]*) Graphic file \(type / ) {
+ if ( /^File: (.+) Graphic file \(type / ) {
# First line of message from includegraphics/x
- $dependents{$1} = 1;
+ $dependents{clean_file_name($1)} = 1;
next LINE;
}
# Now test for generic lines to ignore, only after special cases!
@@ -3140,7 +3290,7 @@ LINE:
# Array of new candidate include files; sometimes more than one.
my @new_includes = ();
my $quoted = 0;
- if ( /^\"([^\(^\)^\"]+)\"/ ) {
+ if ( /^\"([^\"]+)\"/ ) {
# Quoted file name, as from MikTeX
$quoted = 1;
}
@@ -3254,8 +3404,8 @@ CANDIDATE:
# If the file still is not found, assume non-existent;
my @kpse_result = kpsewhich( $candidate );
if ($#kpse_result > -1) {
- $dependents{$kpse_result[0]} = 4;
delete $dependents{$candidate};
+ $dependents{$kpse_result[0]} = 4;
next CANDIDATE;
}
else {
@@ -3360,7 +3510,6 @@ CANDIDATE_PAIR:
foreach (@dependents) {
print " '$_' ";
if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
- print "\n";
if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
print "\n";
}
@@ -3378,8 +3527,7 @@ CANDIDATE_PAIR:
}
if ( $misparse > 0 ) {
- print "$misparse\n";
- print "Apparent input files apparently from misunderstood lines in .log file:\n";
+ print "Possible input files, perhaps from misunderstood lines in .log file:\n";
foreach ( @misparse ) { print " $_\n"; }
}
}
@@ -3389,8 +3537,8 @@ CANDIDATE_PAIR:
#************************************************************
sub parse_aux {
- #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files )
- # Parse aux_file (recursively) for bib files.
+ #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files, \@new_bst_files )
+ # Parse aux_file (recursively) for bib files, and bst files.
# If can't open aux file, then
# Return 0 and leave @new_bib_files empty
# Else set @new_bib_files from information in the aux files
@@ -3404,8 +3552,10 @@ sub parse_aux {
my $aux_file = $_[0];
local $Pbib_files = $_[1];
local $Paux_files = $_[2];
+ local $Pbst_files = $_[3];
@$Pbib_files = ();
+ @$Pbst_files = ();
@$Paux_files = ();
parse_aux1( $aux_file );
@@ -3413,6 +3563,7 @@ sub parse_aux {
return 0;
}
@$Pbib_files = uniqs( @$Pbib_files );
+ @$Pbst_files = uniqs( @$Pbst_files );
if ( $#{$Pbib_files} == -1 ) {
warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
@@ -3421,6 +3572,8 @@ sub parse_aux {
my $bibret = &find_file_list1( $Pbib_files, $Pbib_files,
'.bib', \@BIBINPUTS );
@$Pbib_files = uniqs( @$Pbib_files );
+ &find_file_list1( $Pbst_files, $Pbst_files, '.bst' );
+ @$Pbst_files = uniqs( @$Pbst_files );
if ($bibret == 0) {
warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
unless $silent;
@@ -3468,6 +3621,11 @@ AUX_LINE:
# (Without the '.bib' extension)
push( @$Pbib_files, split /,/, $1 );
}
+ elsif ( /^\\bibstyle\{(.*)\}/ ) {
+ # \\bibstyle{bst_file_name}
+ # (Without the '.bst' extension)
+ push( @$Pbst_files, $1 );
+ }
elsif ( /^\\\@input\{(.*)\}/ ) {
# \\@input{next_aux_file_name}
&parse_aux1( $1 );
@@ -3968,9 +4126,10 @@ sub rdb_set_from_logB {
foreach my $bbl_file ( uniqs( @bbl_files ) ) {
my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
$bbl_base = $bbl_path.$bbl_base;
- my @new_bib_files;
- my @new_aux_files;
- &parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files );
+ my @new_bib_files = ();
+ my @new_aux_files = ();
+ my @new_bst_files = ();
+ &parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files, \@new_bst_files );
my $from_rule = "bibtex $bbl_base";
print "!!!===Dealing with rule '$from_rule'\n"
if ($diagnostics);
@@ -3982,7 +4141,7 @@ sub rdb_set_from_logB {
}
local %old_sources = ();
rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
- foreach my $source ( @new_bib_files, @new_aux_files ) {
+ foreach my $source ( @new_bib_files, @new_aux_files, @new_bst_files ) {
print " === Source file '$source' for '$from_rule'\n"
if ($diagnostics);
rdb_ensure_file( $from_rule, $source );
@@ -4982,6 +5141,11 @@ sub rdb_run1 {
elsif ($retcode == 1) {
push @warnings, "Bibtex warnings for '$$Pbase'";
}
+ elsif ($retcode == 10) {
+ push @warnings, "Bibtex found no citations for '$$Pbase'";
+ # But this is an innocuous error, so fix return code
+ $return = 0;
+ }
}
$updated = 1;
@@ -5986,6 +6150,13 @@ sub get_time_size_raw
#************************************************************
+sub processing_time
+{ my ($user, $system, $cuser, $csystem) = times();
+ return $user + $system + $cuser + $csystem;
+}
+
+#************************************************************
+
sub get_checksum_md5 {
my $source = shift;
my $input = new FileHandle;
@@ -6040,38 +6211,41 @@ sub find_file1 {
# On success: full_name = full name with path, retcode = 0
# On failure: full_name = given name, retcode = 1
- my $name = $_[0];
- # Make local copy of path, since we may rewrite it!
- my @path = @{$_[1]};
- if ( $name =~ /^\// ) {
- # Absolute path (if under UNIX)
- # This needs fixing, in general
- if (-e $name) { return( $name, 0 );}
- else { return( $name, 1 );}
- }
- foreach my $dir ( @path ) {
- #??print "-------------dir='$dir', ";
- # Make $dir concatenatable, and empty for current dir:
- if ( $dir eq '.' ) {
- $dir = '';
- }
- elsif ( $dir =~ /[\/\\:]$/ ) {
- #OK if dir ends in / or \ or :
- }
- elsif ( $dir ne '' ) {
- #Append directory separator only to non-empty dir
- $dir = "$dir/";
- }
- #?? print " newdir='$dir'\n";
- if (-e "$dir$name") {
- return("$dir$name", 0);
- }
- }
- my @kpse_result = kpsewhich( $name );
- if ($#kpse_result > -1) {
- return( $kpse_result[0], 0);
- }
- return("$name" , 1);
+ my $name = $_[0];
+ # Make local copy of path, since we may rewrite it!
+ my @path = ();
+ if ($_[1]) {
+ @path = @{$_[1]};
+ }
+ if ( $name =~ /^\// ) {
+ # Absolute path (if under UNIX)
+ # This needs fixing, in general
+ if (-e $name) { return( $name, 0 );}
+ else { return( $name, 1 );}
+ }
+ foreach my $dir ( @path ) {
+ #??print "-------------dir='$dir', ";
+ # Make $dir concatenatable, and empty for current dir:
+ if ( $dir eq '.' ) {
+ $dir = '';
+ }
+ elsif ( $dir =~ /[\/\\:]$/ ) {
+ #OK if dir ends in / or \ or :
+ }
+ elsif ( $dir ne '' ) {
+ #Append directory separator only to non-empty dir
+ $dir = "$dir/";
+ }
+ #?? print " newdir='$dir'\n";
+ if (-e "$dir$name") {
+ return("$dir$name", 0);
+ }
+ }
+ my @kpse_result = kpsewhich( $name );
+ if ($#kpse_result > -1) {
+ return( $kpse_result[0], 0);
+ }
+ return("$name" , 1);
} #END find_file1
#************************************************************
@@ -6419,7 +6593,11 @@ sub tempfile1 {
sub Run_msg {
# Same as Run, but give message about my running
warn_running( "Running '$_[0]'" );
- Run($_[0]);
+ my $time1 = processing_time();
+ my ($pid, $return) = Run($_[0]);
+ my $time = processing_time() - $time1;
+ push @timings, "'$_[0]': time = $time\n";
+ return ($pid, $return);
}
sub Run {