works for me
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Sat, 03 Nov 2012 21:01:49 +0100
changeset 0 491292dcec7f
child 1 383d9f5021f8
works for me
.hgignore
.perltidyrc
pdd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.perltidyrc	Sat Nov 03 21:01:49 2012 +0100
@@ -0,0 +1,3 @@
+--paren-tightness=2
+--square-bracket-tightness=2
+--nospace-for-semicolon
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pdd	Sat Nov 03 21:01:49 2012 +0100
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+use 5.010;
+use strict;
+use warnings;
+use threads;
+
+sub dd;
+sub timer;
+sub main;
+
+MAIN: {
+    my $dd;
+
+    $SIG{INT} = sub {
+        if (defined $dd) {
+            warn "Got $_[0], going to kill dd(pid:$dd)\n";
+            kill $_[0] => $dd;
+        }
+    };
+
+    say "[dd @ARGV]";
+
+    my ($if) = map /^if=(.*)/ => @ARGV;
+    my $ifsize = -s (defined $if ? $if : \*STDIN);
+
+    $dd = dd @ARGV;
+
+    # the timer runs in its own thread, there it will
+    # send a USR1 every now and then to the $dd process
+
+    my $timer = threads->create(\&timer, $dd);
+
+    printf "%8s %8s %8s %15s %3s\n", 
+	"time", "MB", "M/s", "speed", "done";
+
+    my ($speed, $time, $size) = (0, 0, 0);
+    my @output = ();
+    while (<DD>) {
+	push @output, $_;
+
+        /^(?<size>\d+)
+	    \s+bytes.*copied,\s+
+	  (?<time>\d+\.\d+)\ss,\s
+	  (?<speed>.*)/x
+          or next;
+
+	@output = ();
+        $speed = $+{speed};
+        my $dt = $+{time} - $time;
+        my $ds = $+{size} - $size;
+
+        printf "%8.3f %8.3f %8.3f %15s %3d\n",
+          $+{time}, $+{size} / 2**20, $dt ? $ds / 2**20 / $dt : "-0", 
+	  $+{speed},
+	  $ifsize? $+{size}/$ifsize*100 : 0;
+
+        $time = $+{time};
+        $size = $+{size};
+    }
+
+    $timer->kill("KILL");
+    $timer->join;
+
+    if (defined $dd) {
+	waitpid($dd, 0) == $dd or die "unexpected kid died\n";
+	die @output if $?;
+    }
+
+    say "[dd @ARGV] => $speed";
+
+    exit 0;
+}
+
+sub dd {
+    my @args = @_;
+    my $pid = open(DD, "-|");
+    if ($pid == 0) {
+        open(STDERR, ">&STDOUT");
+        exec("dd", @args);
+        die "Can't exec dd: $!\n";
+    }
+    return $pid;
+}
+
+sub timer {
+    my $pid = shift;
+    local $SIG{"KILL"} = sub { threads->exit };
+    my $i = 0;
+
+    while (1) {
+        sleep 1;
+        kill "USR1" => $pid
+          if ++$i % 10 == 0;
+    }
+}
+