dd: add status=progress support
This reports the current status on a single line every second, mirroring similar functionality in GNU dd, and carefully interacts with SIGINFO. PR: 229615 Submitted by: Thomas Hurst <tom@hur.st> (modified for style(9) nits by me) MFC after: 1 week
This commit is contained in:
parent
f032f7b307
commit
4767c42c11
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=337505
@ -306,6 +306,8 @@ f_status(char *arg)
|
|||||||
ddflags |= C_NOINFO;
|
ddflags |= C_NOINFO;
|
||||||
else if (strcmp(arg, "noxfer") == 0)
|
else if (strcmp(arg, "noxfer") == 0)
|
||||||
ddflags |= C_NOXFER;
|
ddflags |= C_NOXFER;
|
||||||
|
else if (strcmp(arg, "progress") == 0)
|
||||||
|
ddflags |= C_PROGRESS;
|
||||||
else
|
else
|
||||||
errx(1, "unknown status %s", arg);
|
errx(1, "unknown status %s", arg);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
|
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 2, 2017
|
.Dd August 8, 2018
|
||||||
.Dt DD 1
|
.Dt DD 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -164,12 +164,14 @@ bytes per second.
|
|||||||
Where
|
Where
|
||||||
.Cm value
|
.Cm value
|
||||||
is one of the symbols from the following list.
|
is one of the symbols from the following list.
|
||||||
.Bl -tag -width "noxfer"
|
.Bl -tag -width "progress"
|
||||||
.It Cm noxfer
|
.It Cm noxfer
|
||||||
Do not print the transfer statistics as the last line of status output.
|
Do not print the transfer statistics as the last line of status output.
|
||||||
.It Cm none
|
.It Cm none
|
||||||
Do not print the status output.
|
Do not print the status output.
|
||||||
Error messages are shown; informational messages are not.
|
Error messages are shown; informational messages are not.
|
||||||
|
.It Cm progress
|
||||||
|
Print basic transfer statistics once per second.
|
||||||
.El
|
.El
|
||||||
.It Cm conv Ns = Ns Ar value Ns Op , Ns Ar value ...
|
.It Cm conv Ns = Ns Ar value Ns Op , Ns Ar value ...
|
||||||
Where
|
Where
|
||||||
|
14
bin/dd/dd.c
14
bin/dd/dd.c
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#include <sys/mtio.h>
|
#include <sys/mtio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <capsicum_helpers.h>
|
#include <capsicum_helpers.h>
|
||||||
@ -89,6 +90,7 @@ const u_char *ctab; /* conversion table */
|
|||||||
char fill_char; /* Character to fill with if defined */
|
char fill_char; /* Character to fill with if defined */
|
||||||
size_t speed = 0; /* maximum speed, in bytes per second */
|
size_t speed = 0; /* maximum speed, in bytes per second */
|
||||||
volatile sig_atomic_t need_summary;
|
volatile sig_atomic_t need_summary;
|
||||||
|
volatile sig_atomic_t need_progress;
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc __unused, char *argv[])
|
main(int argc __unused, char *argv[])
|
||||||
@ -102,6 +104,7 @@ main(int argc __unused, char *argv[])
|
|||||||
err(1, "unable to enter capability mode");
|
err(1, "unable to enter capability mode");
|
||||||
|
|
||||||
(void)signal(SIGINFO, siginfo_handler);
|
(void)signal(SIGINFO, siginfo_handler);
|
||||||
|
(void)signal(SIGALRM, sigalrm_handler);
|
||||||
(void)signal(SIGINT, terminate);
|
(void)signal(SIGINT, terminate);
|
||||||
|
|
||||||
atexit(summary);
|
atexit(summary);
|
||||||
@ -281,6 +284,14 @@ setup(void)
|
|||||||
ctab = casetab;
|
ctab = casetab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ddflags & C_PROGRESS)) {
|
||||||
|
struct itimerval timer = {
|
||||||
|
.it_interval = { .tv_sec = 1, .tv_usec = 0 },
|
||||||
|
.it_value = { .tv_sec = 1, .tv_usec = 0 },
|
||||||
|
};
|
||||||
|
setitimer(ITIMER_REAL, &timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &st.start))
|
if (clock_gettime(CLOCK_MONOTONIC, &st.start))
|
||||||
err(1, "clock_gettime");
|
err(1, "clock_gettime");
|
||||||
}
|
}
|
||||||
@ -461,6 +472,9 @@ dd_in(void)
|
|||||||
if (need_summary) {
|
if (need_summary) {
|
||||||
summary();
|
summary();
|
||||||
}
|
}
|
||||||
|
if (need_progress) {
|
||||||
|
progress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,5 +100,6 @@ typedef struct {
|
|||||||
#define C_STATUS 0x08000000
|
#define C_STATUS 0x08000000
|
||||||
#define C_NOXFER 0x10000000
|
#define C_NOXFER 0x10000000
|
||||||
#define C_NOINFO 0x20000000
|
#define C_NOINFO 0x20000000
|
||||||
|
#define C_PROGRESS 0x40000000
|
||||||
|
|
||||||
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)
|
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)
|
||||||
|
@ -46,7 +46,9 @@ void pos_in(void);
|
|||||||
void pos_out(void);
|
void pos_out(void);
|
||||||
double secs_elapsed(void);
|
double secs_elapsed(void);
|
||||||
void summary(void);
|
void summary(void);
|
||||||
|
void progress(void);
|
||||||
void siginfo_handler(int);
|
void siginfo_handler(int);
|
||||||
|
void sigalrm_handler(int);
|
||||||
void terminate(int);
|
void terminate(int);
|
||||||
void unblock(void);
|
void unblock(void);
|
||||||
void unblock_close(void);
|
void unblock_close(void);
|
||||||
@ -66,3 +68,4 @@ extern const u_char a2ibm_32V[], a2ibm_POSIX[];
|
|||||||
extern u_char casetab[];
|
extern u_char casetab[];
|
||||||
extern char fill_char;
|
extern char fill_char;
|
||||||
extern volatile sig_atomic_t need_summary;
|
extern volatile sig_atomic_t need_summary;
|
||||||
|
extern volatile sig_atomic_t need_progress;
|
||||||
|
@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
|
|
||||||
|
static int need_newline;
|
||||||
|
|
||||||
double
|
double
|
||||||
secs_elapsed(void)
|
secs_elapsed(void)
|
||||||
{
|
{
|
||||||
@ -83,6 +85,9 @@ summary(void)
|
|||||||
if (ddflags & C_NOINFO)
|
if (ddflags & C_NOINFO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (need_newline && !need_summary)
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
secs = secs_elapsed();
|
secs = secs_elapsed();
|
||||||
|
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
@ -102,6 +107,28 @@ summary(void)
|
|||||||
need_summary = 0;
|
need_summary = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
progress(void)
|
||||||
|
{
|
||||||
|
double secs;
|
||||||
|
static int lastlen;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
secs = secs_elapsed();
|
||||||
|
len = fprintf(stderr,
|
||||||
|
"\r%ju bytes transferred in %.0f secs (%.0f bytes/sec)",
|
||||||
|
st.bytes, secs, st.bytes / secs);
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
if (len < lastlen)
|
||||||
|
(void)fprintf(stderr, "%*s", len - lastlen, "");
|
||||||
|
lastlen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_newline = 1;
|
||||||
|
need_progress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
siginfo_handler(int signo __unused)
|
siginfo_handler(int signo __unused)
|
||||||
@ -110,6 +137,14 @@ siginfo_handler(int signo __unused)
|
|||||||
need_summary = 1;
|
need_summary = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
void
|
||||||
|
sigalrm_handler(int signo __unused)
|
||||||
|
{
|
||||||
|
|
||||||
|
need_progress = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
terminate(int sig)
|
terminate(int sig)
|
||||||
|
Loading…
Reference in New Issue
Block a user