Changeset View
Changeset View
Standalone View
Standalone View
head/bin/dd/misc.c
Show All 40 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <inttypes.h> | #include <inttypes.h> | ||||
#include <libutil.h> | |||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <time.h> | #include <time.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "dd.h" | #include "dd.h" | ||||
#include "extern.h" | #include "extern.h" | ||||
static int need_newline; | |||||
double | double | ||||
secs_elapsed(void) | secs_elapsed(void) | ||||
{ | { | ||||
struct timespec end, ts_res; | struct timespec end, ts_res; | ||||
double secs, res; | double secs, res; | ||||
if (clock_gettime(CLOCK_MONOTONIC, &end)) | if (clock_gettime(CLOCK_MONOTONIC, &end)) | ||||
err(1, "clock_gettime"); | err(1, "clock_gettime"); | ||||
Show All 11 Lines | |||||
void | void | ||||
summary(void) | summary(void) | ||||
{ | { | ||||
double secs; | double secs; | ||||
if (ddflags & C_NOINFO) | if (ddflags & C_NOINFO) | ||||
return; | return; | ||||
if (need_newline && !need_summary) | if (ddflags & C_PROGRESS) | ||||
fprintf(stderr, "\n"); | fprintf(stderr, "\n"); | ||||
secs = secs_elapsed(); | secs = secs_elapsed(); | ||||
(void)fprintf(stderr, | (void)fprintf(stderr, | ||||
"%ju+%ju records in\n%ju+%ju records out\n", | "%ju+%ju records in\n%ju+%ju records out\n", | ||||
st.in_full, st.in_part, st.out_full, st.out_part); | st.in_full, st.in_part, st.out_full, st.out_part); | ||||
if (st.swab) | if (st.swab) | ||||
(void)fprintf(stderr, "%ju odd length swab %s\n", | (void)fprintf(stderr, "%ju odd length swab %s\n", | ||||
st.swab, (st.swab == 1) ? "block" : "blocks"); | st.swab, (st.swab == 1) ? "block" : "blocks"); | ||||
if (st.trunc) | if (st.trunc) | ||||
(void)fprintf(stderr, "%ju truncated %s\n", | (void)fprintf(stderr, "%ju truncated %s\n", | ||||
st.trunc, (st.trunc == 1) ? "block" : "blocks"); | st.trunc, (st.trunc == 1) ? "block" : "blocks"); | ||||
if (!(ddflags & C_NOXFER)) { | if (!(ddflags & C_NOXFER)) { | ||||
(void)fprintf(stderr, | (void)fprintf(stderr, | ||||
"%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n", | "%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n", | ||||
st.bytes, secs, st.bytes / secs); | st.bytes, secs, st.bytes / secs); | ||||
} | } | ||||
need_summary = 0; | need_summary = 0; | ||||
} | } | ||||
void | void | ||||
progress(void) | progress(void) | ||||
{ | { | ||||
static int outlen; | |||||
char si[4 + 1 + 2 + 1]; /* 123 <space> <suffix> NUL */ | |||||
char iec[4 + 1 + 2 + 1]; /* 123 <space> <suffix> NUL */ | |||||
char persec[4 + 1 + 2 + 1]; /* 123 <space> <suffix> NUL */ | |||||
char *buf; | |||||
double secs; | double secs; | ||||
static int lastlen; | |||||
int len; | |||||
secs = secs_elapsed(); | secs = secs_elapsed(); | ||||
len = fprintf(stderr, | humanize_number(si, sizeof(si), (int64_t)st.bytes, "B", HN_AUTOSCALE, | ||||
"\r%ju bytes transferred in %.0f secs (%.0f bytes/sec)", | HN_DECIMAL | HN_DIVISOR_1000); | ||||
st.bytes, secs, st.bytes / secs); | humanize_number(iec, sizeof(iec), (int64_t)st.bytes, "B", HN_AUTOSCALE, | ||||
HN_DECIMAL | HN_IEC_PREFIXES); | |||||
if (len > 0) { | humanize_number(persec, sizeof(iec), (int64_t)(st.bytes / secs), "B", | ||||
if (len < lastlen) | HN_AUTOSCALE, HN_DECIMAL | HN_DIVISOR_1000); | ||||
(void)fprintf(stderr, "%*s", len - lastlen, ""); | asprintf(&buf, " %'ju bytes (%s, %s) transferred %.3fs, %s/s", | ||||
lastlen = len; | (uintmax_t)st.bytes, si, iec, secs, persec); | ||||
} | outlen = fprintf(stderr, "%-*s\r", outlen, buf); | ||||
fflush(stderr); | |||||
need_newline = 1; | free(buf); | ||||
need_progress = 0; | need_progress = 0; | ||||
} | } | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
void | void | ||||
siginfo_handler(int signo __unused) | siginfo_handler(int signo __unused) | ||||
{ | { | ||||
need_summary = 1; | need_summary = 1; | ||||
} | } | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
void | void | ||||
sigalrm_handler(int signo __unused) | sigalarm_handler(int signo __unused) | ||||
{ | { | ||||
need_progress = 1; | need_progress = 1; | ||||
} | } | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
void | void | ||||
terminate(int sig) | terminate(int sig) | ||||
{ | { | ||||
summary(); | summary(); | ||||
_exit(sig == 0 ? 0 : 1); | _exit(sig == 0 ? 0 : 1); | ||||
} | } |