static struct timeval last_time; /* time last time we updated */
static struct avg avg_rate = AVG_INIT;
static int bad_err; /* most recent error code */
+static FILE *progressfp; /* file on which to trace progress data */
static const char throbber[] = "|<-<|>->"; /* throbber pattern */
static unsigned throbix = 0; /* current throbber index */
ndone += pos - last_pos; last_time = now; last_pos = pos;
}
+ /* Trace progress state if requested. */
+ if (progressfp) {
+ fprintf(progressfp, "%10ju.%06ld %"PRIuSEC" %f\n",
+ (uintmax_t)now.tv_sec, now.tv_usec,
+ ndone,
+ (nsectors - ndone)/current_avg(&avg_rate));
+ check_write(progressfp, "progress trace file");
+ }
+
/* Advance the throbber character. */
throbix++; if (!throbber[throbix]) throbix = 0;
}
/* First up, handle the command-line options. */
for (;;) {
- opt = getopt(argc, argv, "hB:E:FR:X:b:cir:s"); if (opt < 0) break;
+ opt = getopt(argc, argv, "hB:E:FP:R:X:b:cir:s"); if (opt < 0) break;
switch (opt) {
/* `-h': Help. */
*/
case 'F': f |= f_fixup; break;
+ /* `-P FILE' (undocumented): trace progress state to FILE. */
+ case 'P':
+ if (progressfp) bail("progress trace file already set");
+ progressfp = fopen(optarg, "w");
+ if (!progressfp)
+ bail_syserr(errno, "failed to open progress trace file `%s'",
+ optarg);
+ break;
+
/* `-R FILE': Read ranges to retry from FILE. Retry ranges are
* converted into `EV_WRITE' and `EV_STOP' events.
*/
if (outfd >= 0) close(outfd);
carefully_fclose(mapfp, "bad-sector region map");
carefully_fclose(errfp, "bad-sector error log");
+ carefully_fclose(progressfp, "progress trace file");
progress_free(&progress);
/* We're done! */