cmd_dd:support dd can do verify
After writing the file, compare the contents of the two files again Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
parent
c2f07a4d5a
commit
14465b85c4
@ -160,9 +160,9 @@ static const struct cmdmap_s g_cmdmap[] =
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLE_DD
|
||||
{ "dd", cmd_dd, 3, 6,
|
||||
{ "dd", cmd_dd, 3, 7,
|
||||
"if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] "
|
||||
"[skip=<sectors>]" },
|
||||
"[skip=<sectors>] [verify]" },
|
||||
# endif
|
||||
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_DELROUTE)
|
||||
|
@ -71,6 +71,7 @@ struct dd_s
|
||||
uint32_t nsectors; /* Number of sectors to transfer */
|
||||
uint32_t skip; /* The number of sectors skipped on input */
|
||||
bool eof; /* true: The end of the input or output file has been hit */
|
||||
bool verify; /* true: Verify infile and outfile correctness */
|
||||
uint16_t sectsize; /* Size of one sector */
|
||||
uint16_t nbytes; /* Number of valid bytes in the buffer */
|
||||
FAR uint8_t *buffer; /* Buffer of data to write to the output file */
|
||||
@ -171,7 +172,8 @@ static inline int dd_infopen(FAR const char *name, FAR struct dd_s *dd)
|
||||
|
||||
static inline int dd_outfopen(FAR const char *name, FAR struct dd_s *dd)
|
||||
{
|
||||
dd->outfd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
dd->outfd = open(name, (dd->verify ? O_RDWR : O_WRONLY) |
|
||||
O_CREAT | O_TRUNC, 0644);
|
||||
if (dd->outfd < 0)
|
||||
{
|
||||
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
|
||||
@ -182,6 +184,100 @@ static inline int dd_outfopen(FAR const char *name, FAR struct dd_s *dd)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int dd_verify(FAR const char *infile, FAR const char *outfile,
|
||||
FAR struct dd_s *dd)
|
||||
{
|
||||
FAR uint8_t *buffer;
|
||||
int sector = 0;
|
||||
int ret = OK;
|
||||
|
||||
ret = lseek(dd->infd, dd->skip ? dd->skip * dd->sectsize : 0, SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "lseek", NSH_ERRNO);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dd->eof = 0;
|
||||
ret = lseek(dd->outfd, 0, SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "lseek", NSH_ERRNO);
|
||||
return ret;
|
||||
}
|
||||
|
||||
buffer = malloc(dd->sectsize);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
while (!dd->eof && sector < dd->nsectors)
|
||||
{
|
||||
ret = dd_read(dd);
|
||||
if (ret < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ret = read(dd->outfd, buffer, dd->nbytes);
|
||||
if (ret != dd->nbytes)
|
||||
{
|
||||
nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "read", NSH_ERRNO);
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(dd->buffer, buffer, dd->nbytes) != 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
nsh_output(dd->vtbl, "infile sector %d", sector);
|
||||
for (i = 0; i < dd->nbytes; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
{
|
||||
nsh_output(dd->vtbl, "\n");
|
||||
}
|
||||
|
||||
nsh_output(dd->vtbl, "%02x", dd->buffer[i]);
|
||||
if (i + 1 % 2 == 0)
|
||||
{
|
||||
nsh_output(dd->vtbl, " ");
|
||||
}
|
||||
}
|
||||
|
||||
nsh_output(dd->vtbl, "\noutfile sector %d", sector);
|
||||
for (i = 0; i < dd->nbytes; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
{
|
||||
nsh_output(dd->vtbl, "\n");
|
||||
}
|
||||
|
||||
nsh_output(dd->vtbl, "%02x", dd->buffer[i]);
|
||||
if (i + 1 % 2 == 0)
|
||||
{
|
||||
nsh_output(dd->vtbl, " ");
|
||||
}
|
||||
}
|
||||
|
||||
nsh_output(dd->vtbl, "\n");
|
||||
ret = ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sector++;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "dd_verify", ret);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -262,6 +358,10 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
||||
{
|
||||
dd.skip = atoi(&argv[i][5]);
|
||||
}
|
||||
else if (strncmp(argv[i], "verify", 6) == 0)
|
||||
{
|
||||
dd.verify = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CAN_PIPE_FROM_STD
|
||||
@ -360,6 +460,11 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
||||
/ ((double)elapsed / USEC_PER_SEC)));
|
||||
#endif
|
||||
|
||||
if (ret == 0 && dd.verify)
|
||||
{
|
||||
ret = dd_verify(infile, outfile, &dd);
|
||||
}
|
||||
|
||||
errout_with_outf:
|
||||
close(dd.outfd);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user