Implement GNU's extension of 'status' operand. The GNU syntax is

borrowed where syntax status=noxfer means no transfer statistics
and status=none means no status information at all.

This feature is useful because the statistics information can
sometimes be annoying, and redirecting stderr to /dev/null would
mean error messages also gets silenced.

Obtained from:	OpenBSD
MFC after:	2 weeks
This commit is contained in:
Xin LI 2014-04-03 00:55:16 +00:00
parent d303275e19
commit c3f5e9c515
6 changed files with 69 additions and 34 deletions

View File

@ -66,6 +66,7 @@ static void f_obs(char *);
static void f_of(char *);
static void f_seek(char *);
static void f_skip(char *);
static void f_status(char *);
static uintmax_t get_num(const char *);
static off_t get_off_t(const char *);
@ -88,6 +89,7 @@ static const struct arg {
{ "oseek", f_seek, C_SEEK, C_SEEK },
{ "seek", f_seek, C_SEEK, C_SEEK },
{ "skip", f_skip, C_SKIP, C_SKIP },
{ "status", f_status, C_STATUS,C_STATUS },
};
static char *oper;
@ -292,6 +294,18 @@ f_skip(char *arg)
in.offset = get_off_t(arg);
}
static void
f_status(char *arg)
{
if (strcmp(arg, "none") == 0)
ddflags |= C_NOINFO;
else if (strcmp(arg, "noxfer") == 0)
ddflags |= C_NOXFER;
else
errx(1, "unknown status %s", arg);
}
static const struct conv {
const char *name;
u_int set, noset;

View File

@ -32,7 +32,7 @@
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\" $FreeBSD$
.\"
.Dd October 1, 2013
.Dd April 2, 2014
.Dt DD 1
.Os
.Sh NAME
@ -156,6 +156,17 @@ Otherwise, input data is read and discarded.
For pipes, the correct number of bytes is read.
For all other devices, the correct number of blocks is read without
distinguishing between a partial or complete block being read.
.It Cm status Ns = Ns Ar value
Where
.Cm value
is one of the symbols from the following list.
.Bl -tag -width ".Cm noxfer"
.It Cm noxfer
Do not print the transfer statistics as the last line of status output.
.It Cm none
Do not print the status output.
Error messages are shown; informational messages are not.
.El
.It Cm conv Ns = Ns Ar value Ns Op , Ns Ar value ...
Where
.Cm value
@ -410,7 +421,9 @@ utility is expected to be a superset of the
standard.
The
.Cm files
operand and the
and
.Cm status
operands and the
.Cm ascii ,
.Cm ebcdic ,
.Cm ibm ,

View File

@ -76,7 +76,7 @@ STAT st; /* statistics */
void (*cfunc)(void); /* conversion function */
uintmax_t cpy_cnt; /* # of blocks to copy */
static off_t pending = 0; /* pending seek if sparse */
u_int ddflags = 0; /* conversion options */
u_int64_t ddflags = 0; /* conversion options */
size_t cbsz; /* conversion block size */
uintmax_t files_cnt = 1; /* # of files to copy */
const u_char *ctab; /* conversion table */

View File

@ -68,32 +68,35 @@ typedef struct {
} STAT;
/* Flags (in ddflags). */
#define C_ASCII 0x00001
#define C_BLOCK 0x00002
#define C_BS 0x00004
#define C_CBS 0x00008
#define C_COUNT 0x00010
#define C_EBCDIC 0x00020
#define C_FILES 0x00040
#define C_IBS 0x00080
#define C_IF 0x00100
#define C_LCASE 0x00200
#define C_NOERROR 0x00400
#define C_NOTRUNC 0x00800
#define C_OBS 0x01000
#define C_OF 0x02000
#define C_OSYNC 0x04000
#define C_PAREVEN 0x08000
#define C_PARNONE 0x100000
#define C_PARODD 0x200000
#define C_PARSET 0x400000
#define C_SEEK 0x800000
#define C_SKIP 0x1000000
#define C_SPARSE 0x2000000
#define C_SWAB 0x4000000
#define C_SYNC 0x8000000
#define C_UCASE 0x10000000
#define C_UNBLOCK 0x20000000
#define C_FILL 0x40000000
#define C_ASCII 0x000000001
#define C_BLOCK 0x000000002
#define C_BS 0x000000004
#define C_CBS 0x000000008
#define C_COUNT 0x000000010
#define C_EBCDIC 0x000000020
#define C_FILES 0x000000040
#define C_IBS 0x000000080
#define C_IF 0x000000100
#define C_LCASE 0x000000200
#define C_NOERROR 0x000000400
#define C_NOTRUNC 0x000000800
#define C_OBS 0x000001000
#define C_OF 0x000002000
#define C_OSYNC 0x000004000
#define C_PAREVEN 0x000008000
#define C_PARNONE 0x000100000
#define C_PARODD 0x000200000
#define C_PARSET 0x000400000
#define C_SEEK 0x000800000
#define C_SKIP 0x001000000
#define C_SPARSE 0x002000000
#define C_SWAB 0x004000000
#define C_SYNC 0x008000000
#define C_UCASE 0x010000000
#define C_UNBLOCK 0x020000000
#define C_FILL 0x040000000
#define C_STATUS 0x080000000
#define C_NOXFER 0x100000000
#define C_NOINFO 0x200000000
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)

View File

@ -53,7 +53,7 @@ extern STAT st;
extern void (*cfunc)(void);
extern uintmax_t cpy_cnt;
extern size_t cbsz;
extern u_int ddflags;
extern u_int64_t ddflags;
extern uintmax_t files_cnt;
extern const u_char *ctab;
extern const u_char a2e_32V[], a2e_POSIX[];

View File

@ -59,6 +59,9 @@ summary(void)
struct timeval tv;
double secs;
if (ddflags & C_NOINFO)
return;
(void)gettimeofday(&tv, NULL);
secs = tv.tv_sec + tv.tv_usec * 1e-6 - st.start;
if (secs < 1e-6)
@ -72,9 +75,11 @@ summary(void)
if (st.trunc)
(void)fprintf(stderr, "%ju truncated %s\n",
st.trunc, (st.trunc == 1) ? "block" : "blocks");
(void)fprintf(stderr,
"%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n",
st.bytes, secs, st.bytes / secs);
if (!(ddflags & C_NOXFER)) {
(void)fprintf(stderr,
"%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n",
st.bytes, secs, st.bytes / secs);
}
need_summary = 0;
}