c78952
From 384ccb1b44fc23514a59529f58f984dcc4a75cc9 Mon Sep 17 00:00:00 2001
2ae5c1
From: Peter Jones <pjones@redhat.com>
b9efc5
Date: Wed, 26 Feb 2014 21:49:12 -0500
31cddd
Subject: [PATCH] Make "exit" take a return code.
f4c76c
f4c76c
This adds "exit" with a return code.  With this patch, any "exit"
f4c76c
command /may/ include a return code, and on platforms that support
f4c76c
returning with an exit status, we will do so.  By default we return the
f4c76c
same exit status we did before this patch.
f4c76c
f4c76c
Signed-off-by: Peter Jones <pjones@redhat.com>
f4c76c
---
f4c76c
 grub-core/commands/minicmd.c         | 20 ++++++++++++++++----
f4c76c
 grub-core/kern/efi/efi.c             |  9 +++++++--
0ac23e
 grub-core/kern/emu/main.c            |  2 +-
f4c76c
 grub-core/kern/emu/misc.c            |  5 +++--
f4c76c
 grub-core/kern/i386/coreboot/init.c  |  2 +-
f4c76c
 grub-core/kern/i386/qemu/init.c      |  2 +-
f4c76c
 grub-core/kern/ieee1275/init.c       |  2 +-
f4c76c
 grub-core/kern/mips/arc/init.c       |  2 +-
f4c76c
 grub-core/kern/mips/loongson/init.c  |  2 +-
f4c76c
 grub-core/kern/mips/qemu_mips/init.c |  2 +-
6f1e3d
 grub-core/kern/misc.c                |  2 +-
f4c76c
 grub-core/kern/uboot/init.c          |  6 +++---
f4c76c
 grub-core/kern/xen/init.c            |  2 +-
f4c76c
 include/grub/misc.h                  |  2 +-
6f1e3d
 14 files changed, 39 insertions(+), 21 deletions(-)
f4c76c
f4c76c
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
ec4acb
index a3a11824172..b25ca4b9f17 100644
f4c76c
--- a/grub-core/commands/minicmd.c
f4c76c
+++ b/grub-core/commands/minicmd.c
f4c76c
@@ -176,12 +176,24 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
f4c76c
 }
f4c76c
 
f4c76c
 /* exit */
f4c76c
-static grub_err_t __attribute__ ((noreturn))
f4c76c
+static grub_err_t
f4c76c
 grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
f4c76c
-		    int argc __attribute__ ((unused)),
f4c76c
-		    char *argv[] __attribute__ ((unused)))
f4c76c
+		    int argc, char *argv[])
f4c76c
 {
f4c76c
-  grub_exit ();
f4c76c
+  int retval = -1;
f4c76c
+  unsigned long n;
f4c76c
+
f4c76c
+  if (argc < 0 || argc > 1)
f4c76c
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
f4c76c
+
f4c76c
+  if (argc == 1)
f4c76c
+    {
f4c76c
+      n = grub_strtoul (argv[0], 0, 10);
f4c76c
+      if (n != ~0UL)
f4c76c
+	retval = n;
f4c76c
+    }
f4c76c
+
f4c76c
+  grub_exit (retval);
f4c76c
   /* Not reached.  */
f4c76c
 }
f4c76c
 
f4c76c
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
ec4acb
index d467785fc6c..684ca93f8f4 100644
f4c76c
--- a/grub-core/kern/efi/efi.c
f4c76c
+++ b/grub-core/kern/efi/efi.c
6f1e3d
@@ -155,11 +155,16 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int retval)
f4c76c
 {
6f1e3d
+  int rc = GRUB_EFI_LOAD_ERROR;
f4c76c
+
f4c76c
+  if (retval == 0)
f4c76c
+    rc = GRUB_EFI_SUCCESS;
f4c76c
+
f4c76c
   grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
f4c76c
   efi_call_4 (grub_efi_system_table->boot_services->exit,
b9efc5
-              grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
f4c76c
+              grub_efi_image_handle, rc, 0, 0);
f4c76c
   for (;;) ;
f4c76c
 }
f4c76c
 
0ac23e
diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c
ec4acb
index 425bb960347..55ea5a11ccd 100644
0ac23e
--- a/grub-core/kern/emu/main.c
0ac23e
+++ b/grub-core/kern/emu/main.c
bc092b
@@ -67,7 +67,7 @@ grub_reboot (void)
0ac23e
 }
0ac23e
 
0ac23e
 void
0ac23e
-grub_exit (void)
0ac23e
+grub_exit (int retval __attribute__((unused)))
0ac23e
 {
0ac23e
   grub_reboot ();
0ac23e
 }
f4c76c
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
ec4acb
index 76661337f10..82012a72fcb 100644
f4c76c
--- a/grub-core/kern/emu/misc.c
f4c76c
+++ b/grub-core/kern/emu/misc.c
bc092b
@@ -137,9 +137,10 @@ xasprintf (const char *fmt, ...)
f4c76c
 
b9efc5
 #if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+__attribute__ ((noreturn))
f4c76c
+grub_exit (int rc)
f4c76c
 {
f4c76c
-  exit (1);
f4c76c
+  exit (rc < 0 ? 1 : rc);
f4c76c
 }
b9efc5
 #endif
f4c76c
 
f4c76c
diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c
ec4acb
index 3314f027fec..36f9134b7b7 100644
f4c76c
--- a/grub-core/kern/i386/coreboot/init.c
f4c76c
+++ b/grub-core/kern/i386/coreboot/init.c
f4c76c
@@ -41,7 +41,7 @@ extern grub_uint8_t _end[];
f4c76c
 extern grub_uint8_t _edata[];
f4c76c
 
f4c76c
 void  __attribute__ ((noreturn))
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   /* We can't use grub_fatal() in this function.  This would create an infinite
f4c76c
      loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit().  */
f4c76c
diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c
ec4acb
index 271b6fbfabd..9fafe98f015 100644
f4c76c
--- a/grub-core/kern/i386/qemu/init.c
f4c76c
+++ b/grub-core/kern/i386/qemu/init.c
f4c76c
@@ -42,7 +42,7 @@ extern grub_uint8_t _end[];
f4c76c
 extern grub_uint8_t _edata[];
f4c76c
 
f4c76c
 void  __attribute__ ((noreturn))
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   /* We can't use grub_fatal() in this function.  This would create an infinite
f4c76c
      loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit().  */
f4c76c
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
ec4acb
index 12590225eca..e69c0133e69 100644
f4c76c
--- a/grub-core/kern/ieee1275/init.c
f4c76c
+++ b/grub-core/kern/ieee1275/init.c
b9efc5
@@ -68,7 +68,7 @@ grub_addr_t grub_ieee1275_original_stack;
f4c76c
 #endif
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   grub_ieee1275_exit ();
f4c76c
 }
f4c76c
diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c
ec4acb
index 3834a149093..86b3a25ec40 100644
f4c76c
--- a/grub-core/kern/mips/arc/init.c
f4c76c
+++ b/grub-core/kern/mips/arc/init.c
f4c76c
@@ -276,7 +276,7 @@ grub_halt (void)
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   GRUB_ARC_FIRMWARE_VECTOR->exit ();
f4c76c
 
f4c76c
diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c
ec4acb
index 7b96531b983..dff598ca7b0 100644
f4c76c
--- a/grub-core/kern/mips/loongson/init.c
f4c76c
+++ b/grub-core/kern/mips/loongson/init.c
f4c76c
@@ -304,7 +304,7 @@ grub_halt (void)
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   grub_halt ();
f4c76c
 }
f4c76c
diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c
ec4acb
index be88b77d22d..8b6c55ffc01 100644
f4c76c
--- a/grub-core/kern/mips/qemu_mips/init.c
f4c76c
+++ b/grub-core/kern/mips/qemu_mips/init.c
f4c76c
@@ -75,7 +75,7 @@ grub_machine_fini (int flags __attribute__ ((unused)))
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   grub_halt ();
f4c76c
 }
f4c76c
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
ec4acb
index 3b633d51f4c..952411d5dc6 100644
f4c76c
--- a/grub-core/kern/misc.c
f4c76c
+++ b/grub-core/kern/misc.c
6f1e3d
@@ -1095,7 +1095,7 @@ grub_abort (void)
f4c76c
       grub_getkey ();
f4c76c
     }
f4c76c
 
f4c76c
-  grub_exit ();
f4c76c
+  grub_exit (1);
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c
ec4acb
index 3e338645c57..be2a5be1d07 100644
f4c76c
--- a/grub-core/kern/uboot/init.c
f4c76c
+++ b/grub-core/kern/uboot/init.c
bc092b
@@ -39,9 +39,9 @@ extern grub_size_t grub_total_module_size;
bc092b
 static unsigned long timer_start;
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc)
f4c76c
 {
f4c76c
-  grub_uboot_return (0);
f4c76c
+  grub_uboot_return (rc < 0 ? 1 : rc);
f4c76c
 }
f4c76c
 
bc092b
 static grub_uint64_t
bc092b
@@ -78,7 +78,7 @@ grub_machine_init (void)
f4c76c
   if (!ver)
f4c76c
     {
f4c76c
       /* Don't even have a console to log errors to... */
f4c76c
-      grub_exit ();
f4c76c
+      grub_exit (-1);
f4c76c
     }
f4c76c
   else if (ver > API_SIG_VERSION)
f4c76c
     {
f4c76c
diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
ec4acb
index 0559c033c3d..fce526d417b 100644
f4c76c
--- a/grub-core/kern/xen/init.c
f4c76c
+++ b/grub-core/kern/xen/init.c
f4c76c
@@ -549,7 +549,7 @@ grub_machine_init (void)
f4c76c
 }
f4c76c
 
f4c76c
 void
f4c76c
-grub_exit (void)
f4c76c
+grub_exit (int rc __attribute__((unused)))
f4c76c
 {
f4c76c
   struct sched_shutdown arg;
f4c76c
 
f4c76c
diff --git a/include/grub/misc.h b/include/grub/misc.h
ec4acb
index 2a9f87cc255..06208143779 100644
f4c76c
--- a/include/grub/misc.h
f4c76c
+++ b/include/grub/misc.h
f4c76c
@@ -334,7 +334,7 @@ int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
f4c76c
 char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
f4c76c
      __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT;
f4c76c
 char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT;
f4c76c
-void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
f4c76c
+void EXPORT_FUNC(grub_exit) (int rc) __attribute__ ((noreturn));
f4c76c
 grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
f4c76c
 					  grub_uint64_t d,
f4c76c
 					  grub_uint64_t *r);