--- /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;
+ }
+}
+