diff --git a/docs/grub.texi b/docs/grub.texi index e3f155984..321da38f0 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4508,9 +4508,14 @@ on platforms that support CMOS. @node cmp @subsection cmp -@deffn Command cmp file1 file2 -Compare the file @var{file1} with the file @var{file2}. If they differ -in size, print the sizes like this: +@deffn Command cmp [@option{-v}] file1 file2 +Compare the file @var{file1} with the file @var{file2}. If they are completely +identical, @code{$?} will be set to 0. Otherwise, if the files are not identical, +@code{$?} will be set to a nonzero value. + +By default nothing will be output. If the @option{-v} is used, verbose mode is +enabled. In this mode when when the files differ in size, print the sizes like +this: @example Differ in size: 0x1234 [foo], 0x4321 [bar] @@ -4523,7 +4528,6 @@ bytes like this: Differ at the offset 777: 0xbe [foo], 0xef [bar] @end example -If they are completely identical, nothing will be printed. @end deffn diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index e9c3b25d3..46185fbbc 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -22,14 +22,21 @@ #include #include #include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); #define BUFFER_SIZE 512 +static const struct grub_arg_option options[] = + { + {0, 'v', 0, N_("Enable verbose output"), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + static grub_err_t -grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_cmp (grub_extcmd_context_t ctxt, int argc, char **args) { grub_ssize_t rd1, rd2; @@ -38,19 +45,20 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), grub_file_t file2 = 0; char *buf1 = 0; char *buf2 = 0; + grub_err_t err = GRUB_ERR_TEST_FAILURE; if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], - args[1]); + if (ctxt->state[0].set) + grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], args[1]); file1 = grub_file_open (args[0], GRUB_FILE_TYPE_CMP); file2 = grub_file_open (args[1], GRUB_FILE_TYPE_CMP); if (! file1 || ! file2) goto cleanup; - if (grub_file_size (file1) != grub_file_size (file2)) + if (ctxt->state[0].set && (grub_file_size (file1) != grub_file_size (file2))) grub_printf_ (N_("Files differ in size: %llu [%s], %llu [%s]\n"), (unsigned long long) grub_file_size (file1), args[0], (unsigned long long) grub_file_size (file2), args[1]); @@ -78,9 +86,10 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), { if (buf1[i] != buf2[i]) { - grub_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"), - (unsigned long long) (i + pos), buf1[i], - args[0], buf2[i], args[1]); + if (ctxt->state[0].set) + grub_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"), + (unsigned long long) (i + pos), buf1[i], + args[0], buf2[i], args[1]); goto cleanup; } } @@ -90,7 +99,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), while (rd2); /* TRANSLATORS: it's always exactly 2 files. */ - grub_printf_ (N_("The files are identical.\n")); + if (ctxt->state[0].set) + grub_printf_ (N_("The files are identical.\n")); + err = GRUB_ERR_NONE; } cleanup: @@ -102,18 +113,19 @@ cleanup: if (file2) grub_file_close (file2); - return grub_errno; + return err; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(cmp) { - cmd = grub_register_command ("cmp", grub_cmd_cmp, - N_("FILE1 FILE2"), N_("Compare two files.")); + cmd = grub_register_extcmd ("cmp", grub_cmd_cmp, 0, + N_("FILE1 FILE2"), N_("Compare two files."), + options); } GRUB_MOD_FINI(cmp) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); }