From 721d79fb73c526b606ebe338b4220cf51dc5c158 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sat, 12 Apr 2025 18:57:15 +0800 Subject: [PATCH] system/dd: align nshlib/cmd_dd cmd_dd:support dd can do verify After writing the file, compare the contents of the two files again Signed-off-by: anjiahao Signed-off-by: dongjiuzhu1 --- system/dd/dd_main.c | 91 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/system/dd/dd_main.c b/system/dd/dd_main.c index b92c44233..3d6cae02d 100644 --- a/system/dd/dd_main.c +++ b/system/dd/dd_main.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -203,6 +204,75 @@ static inline int dd_outfopen(FAR const char *name, FAR struct dd_s *dd) return OK; } +static int dd_verify(FAR struct dd_s *dd) +{ + FAR uint8_t *buffer; + unsigned sector = 0; + int ret = OK; + + ret = lseek(dd->infd, dd->skip ? dd->skip * dd->sectsize : 0, SEEK_SET); + if (ret < 0) + { + fprintf(stderr, "%s: failed to infd lseek: %s\n", + g_dd, strerror(errno)); + return ret; + } + + dd->eof = 0; + ret = lseek(dd->outfd, 0, SEEK_SET); + if (ret < 0) + { + fprintf(stderr, "%s: failed to outfd lseek: %s\n", + g_dd, strerror(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) + { + fprintf(stderr, "%s: failed to outfd read: %d\n", + g_dd, ret < 0 ? errno : ret); + break; + } + + if (memcmp(dd->buffer, buffer, dd->nbytes) != 0) + { + char msg[32]; + snprintf(msg, sizeof(msg), "infile sector %d", sector); + lib_dumpbuffer(msg, dd->buffer, dd->nbytes); + snprintf(msg, sizeof(msg), "\noutfile sector %d", sector); + lib_dumpbuffer(msg, buffer, dd->nbytes); + ret = ERROR; + break; + } + + sector++; + } + + if (ret < 0) + { + fprintf(stderr, "%s: failed to dd verify: %d\n", + g_dd, ret); + } + + free(buffer); + return ret; +} + /**************************************************************************** * Name: print_usage ****************************************************************************/ @@ -211,7 +281,7 @@ static void print_usage(void) { fprintf(stderr, "usage:\n"); fprintf(stderr, " %s [if=] [of=] [bs=] " - "[count=] [skip=] [seek=] " + "[count=] [skip=] [seek=] [verify] " "[conv=]\n", g_dd); } @@ -267,6 +337,10 @@ int main(int argc, FAR char **argv) { dd.seek = atoi(&argv[i][5]); } + else if (strncmp(argv[i], "verify", 6) == 0) + { + dd.oflags |= O_RDONLY; + } else if (strncmp(argv[i], "conv=", 5) == 0) { const char *cur = &argv[i][5]; @@ -304,6 +378,16 @@ int main(int argc, FAR char **argv) } } + /* If verify enabled, infile and outfile are mandatory */ + + if ((dd.oflags & O_RDONLY) && (infile == NULL || outfile == NULL)) + { + fprintf(stderr, "%s: invalid parameters: %s\n", g_dd, + strerror(EINVAL)); + print_usage(); + goto errout_with_paths; + } + /* Allocate the I/O buffer */ dd.buffer = malloc(dd.sectsize); @@ -400,6 +484,11 @@ int main(int argc, FAR char **argv) (unsigned int)(((double)total / 1024) / ((double)elapsed / USEC_PER_SEC))); + if (ret == 0 && (dd.oflags & O_RDONLY) != 0) + { + ret = dd_verify(&dd); + } + errout_with_outf: close(dd.outfd);