X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=data%2FPVE%2FTools.pm;h=b42a5bb5f603b4ff5b3d13a9503aabb9067f2a64;hp=9ced12aadb0a460315c243d994e683fb6ce7af96;hb=804b104122b78b07f81fdc259db4dd5ab82f016a;hpb=1c50a24addb8c7e589c98c586db86aefd98bea6e diff --git a/data/PVE/Tools.pm b/data/PVE/Tools.pm index 9ced12a..b42a5bb 100644 --- a/data/PVE/Tools.pm +++ b/data/PVE/Tools.pm @@ -13,6 +13,8 @@ use base 'Exporter'; use URI::Escape; use Encode; use Digest::SHA1; +use Text::ParseWords; +use String::ShellQuote; our @EXPORT_OK = qw( lock_file @@ -181,6 +183,7 @@ sub run_command { my $output; my $outfunc; my $errfunc; + my $logfunc; foreach my $p (keys %param) { if ($p eq 'timeout') { @@ -201,6 +204,8 @@ sub run_command { $outfunc = $param{$p}; } elsif ($p eq 'errfunc') { $errfunc = $param{$p}; + } elsif ($p eq 'logfunc') { + $logfunc = $param{$p}; } else { die "got unknown parameter '$p' for run_command\n"; } @@ -222,6 +227,15 @@ sub run_command { local $ENV{LVM_SUPPRESS_FD_WARNINGS} = "1"; $pid = open3($writer, $reader, $error, @$cmd) || die $!; + + # if we pipe fron STDIN, open3 closes STDIN, so we we + # a perl warning "Filehandle STDIN reopened as GENXYZ .. " + # as soon as we open a new file. + # to avoid that we open /dev/null + if (!ref($writer) && !defined(fileno(STDIN))) { + POSIX::close(0); + open(STDIN, "add($reader); + $select->add($reader) if ref($reader); $select->add($error); my $outlog = ''; @@ -264,12 +280,13 @@ sub run_command { } $select->remove ($h) if !$count; if ($h eq $reader) { - if ($outfunc) { + if ($outfunc || $logfunc) { eval { $outlog .= $buf; while ($outlog =~ s/^([^\010\r\n]*)(\r|\n|(\010)+|\r\n)//s) { my $line = $1; - &$outfunc($line); + &$outfunc($line) if $outfunc; + &$logfunc($line) if $logfunc; } }; my $err = $@; @@ -283,12 +300,13 @@ sub run_command { *STDOUT->flush(); } } elsif ($h eq $error) { - if ($errfunc) { + if ($errfunc || $logfunc) { eval { $errlog .= $buf; while ($errlog =~ s/^([^\010\r\n]*)(\r|\n|(\010)+|\r\n)//s) { my $line = $1; - &$errfunc($line); + &$errfunc($line) if $errfunc; + &$logfunc($line) if $logfunc; } }; my $err = $@; @@ -306,7 +324,10 @@ sub run_command { } &$outfunc($outlog) if $outfunc && $outlog; + &$logfunc($outlog) if $logfunc && $outlog; + &$errfunc($errlog) if $errfunc && $errlog; + &$logfunc($errlog) if $logfunc && $errlog; waitpid ($pid, 0); @@ -599,7 +620,7 @@ sub upid_open { my $outfh = IO::File->new ($filename, O_WRONLY|O_CREAT|O_EXCL, $perm) || die "unable to create output file '$filename' - $!\n"; - chown $wwwid, $outfh; + chown $wwwid, -1, $outfh; return $outfh; }; @@ -668,4 +689,54 @@ sub random_ether_addr { return $mac; } +sub shellquote { + my $str = shift; + + return String::ShellQuote::shell_quote($str); +} + +# split an shell argument string into an array, +sub split_args { + my ($str) = @_; + + return $str ? [ Text::ParseWords::shellwords($str) ] : []; +} + +sub dump_logfile { + my ($filename, $start, $limit) = @_; + + my $lines = []; + my $count = 0; + + my $fh = IO::File->new($filename, "r"); + if (!$fh) { + $count++; + push @$lines, { n => $count, t => "unable to open file - $!"}; + return ($count, $lines); + } + + $start = 0 if !$start; + $limit = 50 if !$limit; + + my $line; + while (defined($line = <$fh>)) { + next if $count++ < $start; + next if $limit <= 0; + chomp $line; + push @$lines, { n => $count, t => $line}; + $limit--; + } + + close($fh); + + # HACK: ExtJS store.guaranteeRange() does not like empty array + # so we add a line + if (!$count) { + $count++; + push @$lines, { n => $count, t => "no content"}; + } + + return ($count, $lines); +} + 1;