Blame SOURCES/0020-Don-t-error-on-unset-BootOrder-when-we-re-trying-to-.patch

38ab4d
From 1bc44d6c4fe0498f8ed2c52164f034ba483ccfb2 Mon Sep 17 00:00:00 2001
5fb29d
From: Peter Jones <pjones@redhat.com>
5fb29d
Date: Wed, 15 Oct 2014 10:35:56 -0400
38ab4d
Subject: [PATCH 20/31] Don't error on unset BootOrder when we're trying to add
38ab4d
 to or rm from it.
5fb29d
5fb29d
Also print some better error messases here and there.
5fb29d
5fb29d
Signed-off-by: Peter Jones <pjones@redhat.com>
5fb29d
---
5fb29d
 README                      |   1 -
5fb29d
 src/efibootmgr/efibootmgr.c | 126 +++++++++++++++++++++++++++-----------------
5fb29d
 src/lib/efi.c               |  95 +++++++++++++++++++--------------
5fb29d
 src/man/man8/efibootmgr.8   |   3 --
5fb29d
 4 files changed, 131 insertions(+), 94 deletions(-)
5fb29d
5fb29d
diff --git a/README b/README
5fb29d
index 3bc0a26..edbce4b 100644
5fb29d
--- a/README
5fb29d
+++ b/README
5fb29d
@@ -29,7 +29,6 @@ usage: efibootmgr [options]
5fb29d
 	-O | --delete-bootorder delete BootOrder
5fb29d
 	-p | --part part       (defaults to 1) containing loader
5fb29d
 	-q | --quiet           be quiet
5fb29d
-	--test filename   don't write to NVRAM, write to filename
5fb29d
 	-t | --timeout seconds   Boot manager timeout
5fb29d
 	-T | --delete-timeout    delete Timeout value
5fb29d
 	-u | --unicode | --UCS-2  pass extra args as UCS-2 (default is ASCII)
5fb29d
diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c
5fb29d
index 4d80f87..eb13942 100644
5fb29d
--- a/src/efibootmgr/efibootmgr.c
5fb29d
+++ b/src/efibootmgr/efibootmgr.c
5fb29d
@@ -33,6 +33,7 @@
5fb29d
 #define _GNU_SOURCE
5fb29d
 
5fb29d
 #include <ctype.h>
5fb29d
+#include <err.h>
5fb29d
 #include <stdio.h>
5fb29d
 #include <stdlib.h>
5fb29d
 #include <string.h>
5fb29d
@@ -123,7 +124,7 @@ read_vars(char **namelist,
5fb29d
 	}
5fb29d
 	return;
5fb29d
 err:
5fb29d
-	fprintf(stderr, "efibootmgr: %m\n");
5fb29d
+	warn("efibootmgr");
5fb29d
 	exit(1);
5fb29d
 }
5fb29d
 
5fb29d
@@ -242,16 +243,20 @@ make_boot_var(list_t *boot_list)
5fb29d
 		free_number = opts.bootnum;
5fb29d
 	}
5fb29d
 
5fb29d
-	if (free_number == -1)
5fb29d
+	if (free_number == -1) {
5fb29d
+		warn("efibootmgr: no available boot variables");
5fb29d
 		return NULL;
5fb29d
+	}
5fb29d
 
5fb29d
 	/* Create a new efi_variable_t object
5fb29d
 	   and populate it.
5fb29d
 	*/
5fb29d
 
5fb29d
 	boot = calloc(1, sizeof(*boot));
5fb29d
-	if (!boot)
5fb29d
+	if (!boot) {
5fb29d
+		warn("efibootmgr");
5fb29d
 		return NULL;
5fb29d
+	}
5fb29d
 	if (make_linux_load_option(&boot->data, &boot->data_size) < 0)
5fb29d
 		goto err_boot_entry;
5fb29d
 	if (append_extra_args(&boot->data, &boot->data_size) < 0)
5fb29d
@@ -260,8 +265,10 @@ make_boot_var(list_t *boot_list)
5fb29d
 	boot->num = free_number;
5fb29d
 	boot->guid = EFI_GLOBAL_VARIABLE;
5fb29d
 	rc = asprintf(&boot->name, "Boot%04X", free_number);
5fb29d
-	if (rc < 0)
5fb29d
+	if (rc < 0) {
5fb29d
+		warn("efibootmgr");
5fb29d
 		goto err_boot_entry;
5fb29d
+	}
5fb29d
 	boot->attributes = EFI_VARIABLE_NON_VOLATILE |
5fb29d
 			    EFI_VARIABLE_BOOTSERVICE_ACCESS |
5fb29d
 			    EFI_VARIABLE_RUNTIME_ACCESS;
5fb29d
@@ -272,8 +279,12 @@ make_boot_var(list_t *boot_list)
5fb29d
 	list_add_tail(&boot->list, boot_list);
5fb29d
 	return boot;
5fb29d
 err_boot_entry:
5fb29d
-	if (boot->name)
5fb29d
+	if (boot->name) {
5fb29d
+		warn("Could not set variable %s", boot->name);
5fb29d
 		free(boot->name);
5fb29d
+	} else {
5fb29d
+		warn("Could not set variable");
5fb29d
+	}
5fb29d
 	if (boot->data)
5fb29d
 		free(boot->data);
5fb29d
 	free(boot);
5fb29d
@@ -313,6 +324,15 @@ read_boot_order(efi_variable_t **boot_order)
5fb29d
 }
5fb29d
 
5fb29d
 static int
5fb29d
+set_boot_u16(const char *name, uint16_t num)
5fb29d
+{
5fb29d
+	return efi_set_variable(EFI_GLOBAL_GUID, name, (uint8_t *)&num,
5fb29d
+				sizeof (num), EFI_VARIABLE_NON_VOLATILE |
5fb29d
+					      EFI_VARIABLE_BOOTSERVICE_ACCESS |
5fb29d
+					      EFI_VARIABLE_RUNTIME_ACCESS);
5fb29d
+}
5fb29d
+
5fb29d
+static int
5fb29d
 add_to_boot_order(uint16_t num)
5fb29d
 {
5fb29d
 	efi_variable_t *boot_order = NULL;
5fb29d
@@ -321,8 +341,11 @@ add_to_boot_order(uint16_t num)
5fb29d
 	int rc;
5fb29d
 
5fb29d
 	rc = read_boot_order(&boot_order);
5fb29d
-	if (rc < 0)
5fb29d
+	if (rc < 0) {
5fb29d
+		if (errno == ENOENT)
5fb29d
+			rc = set_boot_u16("BootOrder", num);
5fb29d
 		return rc;
5fb29d
+	}
5fb29d
 
5fb29d
 	/* We've now got an array (in boot_order->data) of the
5fb29d
 	 * boot order.  First add our entry, then copy the old array.
5fb29d
@@ -358,8 +381,11 @@ remove_dupes_from_boot_order(void)
5fb29d
 	int rc;
5fb29d
 
5fb29d
 	rc = read_boot_order(&boot_order);
5fb29d
-	if (rc < 0)
5fb29d
+	if (rc < 0) {
5fb29d
+		if (errno == ENOENT)
5fb29d
+			rc = 0;
5fb29d
 		return rc;
5fb29d
+	}
5fb29d
 
5fb29d
 	old_data = (uint16_t *)(boot_order->data);
5fb29d
 	/* Start with the same size */
5fb29d
@@ -409,8 +435,11 @@ remove_from_boot_order(uint16_t num)
5fb29d
 	int rc;
5fb29d
 
5fb29d
 	rc = read_boot_order(&boot_order);
5fb29d
-	if (rc < 0)
5fb29d
+	if (rc < 0) {
5fb29d
+		if (errno == ENOENT)
5fb29d
+			rc = 0;
5fb29d
 		return rc;
5fb29d
+	}
5fb29d
 
5fb29d
 	/* We've now got an array (in boot_order->data) of the
5fb29d
 	   boot order.  Simply copy the array, skipping the
5fb29d
@@ -470,15 +499,6 @@ read_boot_u16(const char *name)
5fb29d
 }
5fb29d
 
5fb29d
 static int
5fb29d
-set_boot_u16(const char *name, uint16_t num)
5fb29d
-{
5fb29d
-	return efi_set_variable(EFI_GLOBAL_GUID, name, (uint8_t *)&num,
5fb29d
-				sizeof (num), EFI_VARIABLE_NON_VOLATILE |
5fb29d
-					      EFI_VARIABLE_BOOTSERVICE_ACCESS |
5fb29d
-					      EFI_VARIABLE_RUNTIME_ACCESS);
5fb29d
-}
5fb29d
-
5fb29d
-static int
5fb29d
 delete_boot_var(uint16_t num)
5fb29d
 {
5fb29d
 	int rc;
5fb29d
@@ -490,13 +510,18 @@ delete_boot_var(uint16_t num)
5fb29d
 	rc = efi_del_variable(EFI_GLOBAL_GUID, name);
5fb29d
 
5fb29d
 	/* For backwards compatibility, try to delete abcdef entries as well */
5fb29d
-	if (rc < 0 && errno == ENOENT) {
5fb29d
-		snprintf(name, sizeof(name), "Boot%04x", num);
5fb29d
-		rc = efi_del_variable(EFI_GLOBAL_GUID, name);
5fb29d
+	if (rc < 0) {
5fb29d
+		if (errno == ENOENT) {
5fb29d
+			snprintf(name, sizeof(name), "Boot%04x", num);
5fb29d
+			rc = efi_del_variable(EFI_GLOBAL_GUID, name);
5fb29d
+		} else if (errno == EPERM) {
5fb29d
+			warn("Could not delete Boot%04X", num);
5fb29d
+			return rc;
5fb29d
+		}
5fb29d
 	}
5fb29d
 
5fb29d
 	if (rc < 0) {
5fb29d
-		fprintf(stderr,"\nboot entry: %X not found\n\n",num);
5fb29d
+		warnx("Boot entry %04X not found", num);
5fb29d
 		return rc;
5fb29d
 	}
5fb29d
 	list_for_each_safe(pos, n, &boot_entry_list) {
5fb29d
@@ -512,7 +537,6 @@ delete_boot_var(uint16_t num)
5fb29d
 	return 0;
5fb29d
 }
5fb29d
 
5fb29d
-
5fb29d
 static void
5fb29d
 set_var_nums(list_t *list)
5fb29d
 {
5fb29d
@@ -1177,34 +1201,28 @@ main(int argc, char **argv)
5fb29d
 	if (opts.iface && (
5fb29d
 			opts.acpi_hid < 0 || opts.acpi_uid < 0 ||
5fb29d
 			opts.acpi_hid > UINT32_MAX ||
5fb29d
-			opts.acpi_uid > UINT32_MAX)) {
5fb29d
-		fprintf(stderr, "\nYou must specify the ACPI HID and UID when using -i.\n\n");
5fb29d
-		return 1;
5fb29d
-	}
5fb29d
+			opts.acpi_uid > UINT32_MAX))
5fb29d
+		errx(1, "You must specify the ACPI HID and UID when using -i.");
5fb29d
 
5fb29d
-	if (!efi_variables_supported()) {
5fb29d
-		fprintf(stderr, "\nEFI variables are not supported on this system.\n\n");
5fb29d
-		return 1;
5fb29d
-	}
5fb29d
+	if (!efi_variables_supported())
5fb29d
+		errx(2, "EFI variables are not supported on this system.");
5fb29d
 
5fb29d
 	read_boot_var_names(&boot_names);
5fb29d
 	read_vars(boot_names, &boot_entry_list);
5fb29d
 	set_var_nums(&boot_entry_list);
5fb29d
 
5fb29d
 	if (opts.delete_boot) {
5fb29d
-		if (opts.bootnum == -1) {
5fb29d
-			fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n");
5fb29d
-			return 1;
5fb29d
-		}
5fb29d
+		if (opts.bootnum == -1)
5fb29d
+			errx(3, "You must specify a boot entry to delete "
5fb29d
+				"(see the -b option).");
5fb29d
 		else
5fb29d
 			ret = delete_boot_var(opts.bootnum);
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.active >= 0) {
5fb29d
-		if (opts.bootnum == -1) {
5fb29d
-			fprintf(stderr, "\nYou must specify a boot entry to activate (see the -b option).\n\n");
5fb29d
-			return 1;
5fb29d
-		}
5fb29d
+		if (opts.bootnum == -1)
5fb29d
+			errx(4, "You must specify a boot entry to activate "
5fb29d
+				"(see the -b option");
5fb29d
 		else
5fb29d
 			ret=set_active_state();
5fb29d
 	}
5fb29d
@@ -1212,47 +1230,57 @@ main(int argc, char **argv)
5fb29d
 	if (opts.create) {
5fb29d
 		warn_duplicate_name(&boot_entry_list);
5fb29d
 		new_boot = make_boot_var(&boot_entry_list);
5fb29d
-		if (!new_boot) {
5fb29d
-			fprintf(stderr, "\nCould not prepare boot variable: %m\n\n");
5fb29d
-			return 1;
5fb29d
-		}
5fb29d
+		if (!new_boot)
5fb29d
+			err(5, "Could not prepare boot variable");
5fb29d
 
5fb29d
 		/* Put this boot var in the right BootOrder */
5fb29d
 		if (new_boot)
5fb29d
 			ret=add_to_boot_order(new_boot->num);
5fb29d
+		if (ret)
5fb29d
+			err(6, "Could not add entry to BootOrder");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.delete_bootorder) {
5fb29d
 		ret = efi_del_variable(EFI_GLOBAL_GUID, "BootOrder");
5fb29d
+		err(7, "Could not remove entry from BootOrder");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.bootorder) {
5fb29d
 		ret = set_boot_order(opts.keep_old_entries);
5fb29d
+		if (ret)
5fb29d
+			err(8, "Could not set BootOrder");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.deduplicate) {
5fb29d
 		ret = remove_dupes_from_boot_order();
5fb29d
+		if (ret)
5fb29d
+			err(9, "Could not set BootOrder");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.delete_bootnext) {
5fb29d
 		ret = efi_del_variable(EFI_GLOBAL_GUID, "BootNext");
5fb29d
+		if (ret)
5fb29d
+			err(10, "Could not set BootNext");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.delete_timeout) {
5fb29d
 		ret = efi_del_variable(EFI_GLOBAL_GUID, "Timeout");
5fb29d
+		if (ret)
5fb29d
+			err(11, "Could not delete Timeout");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.bootnext >= 0) {
5fb29d
-		if (!is_current_boot_entry(opts.bootnext & 0xFFFF)){
5fb29d
-			fprintf (stderr,"\n\nboot entry %X does not exist\n\n",
5fb29d
-				opts.bootnext);
5fb29d
-			return 1;
5fb29d
-		}
5fb29d
-		ret=set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
5fb29d
+		if (!is_current_boot_entry(opts.bootnext & 0xFFFF))
5fb29d
+			errx(12, "Boot entry %X does not exist", opts.bootnext);
5fb29d
+		ret = set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
5fb29d
+		if (ret)
5fb29d
+			err(13, "Could not set BootNext");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (opts.set_timeout) {
5fb29d
-		ret=set_boot_u16("Timeout", opts.timeout);
5fb29d
+		ret = set_boot_u16("Timeout", opts.timeout);
5fb29d
+		if (ret)
5fb29d
+			err(14, "Could not set Timeout");
5fb29d
 	}
5fb29d
 
5fb29d
 	if (!opts.quiet && ret == 0) {
5fb29d
diff --git a/src/lib/efi.c b/src/lib/efi.c
5fb29d
index 7cdc884..d19c00d 100644
5fb29d
--- a/src/lib/efi.c
5fb29d
+++ b/src/lib/efi.c
5fb29d
@@ -19,6 +19,7 @@
5fb29d
  */
5fb29d
 
5fb29d
 #include <ctype.h>
5fb29d
+#include <err.h>
5fb29d
 #include <stdio.h>
5fb29d
 #include <stdlib.h>
5fb29d
 #include <string.h>
5fb29d
@@ -502,7 +503,6 @@ static ssize_t
5fb29d
 make_disk_load_option(char *disk, uint8_t *buf, size_t size)
5fb29d
 {
5fb29d
 	int disk_fd=0;
5fb29d
-	char buffer[80];
5fb29d
 	char signature[16];
5fb29d
 	int rc, edd_version=0;
5fb29d
 	uint8_t mbr_type=0, signature_type=0;
5fb29d
@@ -514,11 +514,8 @@ make_disk_load_option(char *disk, uint8_t *buf, size_t size)
5fb29d
 	memset(signature, 0, sizeof(signature));
5fb29d
 
5fb29d
 	disk_fd = open(opts.disk, O_RDWR);
5fb29d
-	if (disk_fd == -1) {
5fb29d
-		sprintf(buffer, "Could not open disk %s", opts.disk);
5fb29d
-		perror(buffer);
5fb29d
-		return -1;
5fb29d
-	}
5fb29d
+	if (disk_fd == -1)
5fb29d
+		err(5, "Could not open disk %s", opts.disk);
5fb29d
 
5fb29d
 	if (opts.edd_version) {
5fb29d
 		edd_version = get_edd_version();
5fb29d
@@ -539,12 +536,10 @@ make_disk_load_option(char *disk, uint8_t *buf, size_t size)
5fb29d
 				  &part_start, &part_size, signature,
5fb29d
 				  &mbr_type, &signature_type);
5fb29d
 	close(disk_fd);
5fb29d
-	if (rc) {
5fb29d
-		fprintf(stderr, "Error: no partition information on disk %s.\n"
5fb29d
-			"       Cowardly refusing to create a boot option.\n",
5fb29d
+	if (rc)
5fb29d
+		errx(5, "No partition information on disk %s.\n"
5fb29d
+			"Cowardly refusing to create a boot option.\n",
5fb29d
 			opts.disk);
5fb29d
-		return -1;
5fb29d
-	}
5fb29d
 
5fb29d
 	needed = make_harddrive_device_path(opts.part, part_start, part_size,
5fb29d
 					(uint8_t *)signature, mbr_type,
5fb29d
@@ -724,10 +719,13 @@ make_linux_load_option(uint8_t **data, size_t *data_size)
5fb29d
 	uint8_t *buf;
5fb29d
 	ssize_t needed;
5fb29d
 	off_t buf_offset = 0, desc_offset;
5fb29d
+	int rc;
5fb29d
 
5fb29d
 	load_option = calloc(1, sizeof (*load_option));
5fb29d
-	if (load_option == NULL)
5fb29d
+	if (load_option == NULL) {
5fb29d
+		fprintf(stderr, "efibootmgr: %m\n");
5fb29d
 		return -1;
5fb29d
+	}
5fb29d
 	buf = (uint8_t *)load_option;
5fb29d
 	buf_offset = 0;
5fb29d
 
5fb29d
@@ -755,21 +753,33 @@ make_linux_load_option(uint8_t **data, size_t *data_size)
5fb29d
 	if (opts.iface) {
5fb29d
 		needed = make_net_load_option(opts.iface, NULL, 0);
5fb29d
 		if (needed < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: could not create load option: %m\n");
5fb29d
 			free(buf);
5fb29d
 			return needed;
5fb29d
 		}
5fb29d
 		buf = extend(load_option, load_option_size, needed);
5fb29d
-		make_net_load_option(opts.iface, buf + buf_offset, needed);
5fb29d
+		rc = make_net_load_option(opts.iface, buf + buf_offset, needed);
5fb29d
 		buf_offset += needed;
5fb29d
+		if (rc < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: could not create load option: %m\n");
5fb29d
+			free(buf);
5fb29d
+			return rc;
5fb29d
+		}
5fb29d
 	} else {
5fb29d
 		needed = make_disk_load_option(opts.iface, NULL, 0);
5fb29d
 		if (needed < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: could not create load option: %m\n");
5fb29d
 			free(buf);
5fb29d
 			return needed;
5fb29d
 		}
5fb29d
 		buf = extend(load_option, load_option_size, needed);
5fb29d
-		make_disk_load_option(opts.iface, buf + buf_offset, needed);
5fb29d
+		rc = make_disk_load_option(opts.iface, buf + buf_offset, needed);
5fb29d
 		buf_offset += needed;
5fb29d
+		if (rc < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: could not create load option: %m\n");
5fb29d
+			free(buf);
5fb29d
+			return rc;
5fb29d
+		}
5fb29d
 	}
5fb29d
 
5fb29d
 	load_option->file_path_list_length = buf_offset - desc_offset;
5fb29d
@@ -792,25 +802,25 @@ append_extra_args_ascii(uint8_t **data, size_t *data_size)
5fb29d
 	int i;
5fb29d
 	unsigned long usedchars=0;
5fb29d
 
5fb29d
-	if (!data || *data)
5fb29d
+	if (!data || *data) {
5fb29d
+		errno = EINVAL;
5fb29d
 		return -1;
5fb29d
+	}
5fb29d
 
5fb29d
 	for (i=opts.optind; i < opts.argc; i++)	{
5fb29d
-		int l = strlen(opts.argv[i]) + 1;
5fb29d
+		int l = strlen(opts.argv[i]);
5fb29d
 		int space = (i < opts.argc - 1) ? 1: 0;
5fb29d
-		uint8_t *tmp = realloc(new_data, (usedchars + l + space));
5fb29d
+		uint8_t *tmp = realloc(new_data, (usedchars + l + space + 1));
5fb29d
 		if (tmp == NULL)
5fb29d
 			return -1;
5fb29d
 		new_data = tmp;
5fb29d
 		p = (char *)new_data + usedchars;
5fb29d
 		strcpy(p, opts.argv[i]);
5fb29d
 		usedchars += l;
5fb29d
-		p += l;
5fb29d
 		/* Put a space between args */
5fb29d
 		if (space)
5fb29d
-			p[usedchars++] = ' ';
5fb29d
-		else
5fb29d
-			p[usedchars] = '\0';
5fb29d
+			new_data[usedchars++] = ' ';
5fb29d
+		new_data[usedchars] = '\0';
5fb29d
 	}
5fb29d
 
5fb29d
 	if (!new_data)
5fb29d
@@ -829,8 +839,10 @@ append_extra_args_unicode(uint8_t **data, size_t *data_size)
5fb29d
 	int i;
5fb29d
 	unsigned long usedchars=0;
5fb29d
 
5fb29d
-	if (!data || *data)
5fb29d
+	if (!data || *data) {
5fb29d
+		errno = EINVAL;
5fb29d
 		return -1;
5fb29d
+	}
5fb29d
 
5fb29d
 	for (i = opts.optind; i < opts.argc; i++) {
5fb29d
 		int l = strlen(opts.argv[i]) + 1;
5fb29d
@@ -871,37 +883,31 @@ append_extra_args_file(uint8_t **data, size_t *data_size)
5fb29d
 	size_t maxchars = 0;
5fb29d
 	char *buffer;
5fb29d
 
5fb29d
-	if (!data) {
5fb29d
-		fprintf(stderr, "internal error\n");
5fb29d
-		exit(1);
5fb29d
+	if (!data || *data) {
5fb29d
+		errno = EINVAL;
5fb29d
+		return -1;
5fb29d
 	}
5fb29d
 
5fb29d
 	if (file && strncmp(file, "-", 1))
5fb29d
 		fd = open(file, O_RDONLY);
5fb29d
 
5fb29d
-	if (fd == -1) {
5fb29d
-		perror("Failed to open extra arguments file");
5fb29d
-		exit(1);
5fb29d
-	}
5fb29d
+	if (fd < 0)
5fb29d
+		return -1;
5fb29d
 
5fb29d
 	buffer = malloc(maxchars);
5fb29d
 	do {
5fb29d
 		if (maxchars - appended == 0) {
5fb29d
 			maxchars += 1024;
5fb29d
 			char *tmp = realloc(buffer, maxchars);
5fb29d
-			if (tmp == NULL) {
5fb29d
-				perror("Error reading extra arguments file");
5fb29d
-				exit(1);
5fb29d
-			}
5fb29d
+			if (tmp == NULL)
5fb29d
+				return -1;
5fb29d
 			buffer = tmp;
5fb29d
 		}
5fb29d
 		num_read = read(fd, buffer + appended, maxchars - appended);
5fb29d
-		if (num_read < 0) {
5fb29d
-			perror("Error reading extra arguments file");
5fb29d
-			exit(1);
5fb29d
-		} else if (num_read > 0) {
5fb29d
+		if (num_read < 0)
5fb29d
+			return -1;
5fb29d
+		else if (num_read > 0)
5fb29d
 			appended += num_read;
5fb29d
-		}
5fb29d
 	} while (num_read > 0);
5fb29d
 
5fb29d
 	if (fd != STDIN_FILENO)
5fb29d
@@ -935,14 +941,18 @@ append_extra_args(uint8_t **data, size_t *data_size)
5fb29d
 
5fb29d
 	if (opts.extra_opts_file) {
5fb29d
 		ret = append_extra_args_file(&new_data, &new_data_size);
5fb29d
-		if (ret < 0)
5fb29d
+		if (ret < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
5fb29d
 			return -1;
5fb29d
+		}
5fb29d
 	}
5fb29d
 	if (new_data_size) {
5fb29d
 		ret = add_new_data(data, data_size, new_data, new_data_size);
5fb29d
 		free(new_data);
5fb29d
-		if (ret < 0)
5fb29d
+		if (ret < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
5fb29d
 			return -1;
5fb29d
+		}
5fb29d
 		new_data = NULL;
5fb29d
 		new_data_size = 0;
5fb29d
 	}
5fb29d
@@ -952,6 +962,7 @@ append_extra_args(uint8_t **data, size_t *data_size)
5fb29d
 	else
5fb29d
 		ret = append_extra_args_ascii(&new_data, &new_data_size);
5fb29d
 	if (ret < 0) {
5fb29d
+		fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
5fb29d
 		if (new_data) /* this can't happen, but covscan believes */
5fb29d
 			free(new_data);
5fb29d
 		return -1;
5fb29d
@@ -960,8 +971,10 @@ append_extra_args(uint8_t **data, size_t *data_size)
5fb29d
 		ret = add_new_data(data, data_size, new_data, new_data_size);
5fb29d
 		free(new_data);
5fb29d
 		new_data = NULL;
5fb29d
-		if (ret < 0)
5fb29d
+		if (ret < 0) {
5fb29d
+			fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
5fb29d
 			return -1;
5fb29d
+		}
5fb29d
 		new_data_size = 0;
5fb29d
 	}
5fb29d
 
5fb29d
diff --git a/src/man/man8/efibootmgr.8 b/src/man/man8/efibootmgr.8
5fb29d
index 96071d7..423bc16 100644
5fb29d
--- a/src/man/man8/efibootmgr.8
5fb29d
+++ b/src/man/man8/efibootmgr.8
5fb29d
@@ -93,9 +93,6 @@ Partition number containing the bootloader (defaults to 1)
5fb29d
 \fB-q | --quiet\fR
5fb29d
 Quiet mode - supresses output.
5fb29d
 .TP
5fb29d
-\fB--test \fIfilename\fB\fR
5fb29d
-Don't write to NVRAM, write to \fIfilename\fR\&.
5fb29d
-.TP
5fb29d
 \fB-t | --timeout \fIseconds\fB\fR
5fb29d
 Boot Manager timeout, in \fIseconds\fR\&.
5fb29d
 .TP
5fb29d
-- 
38ab4d
2.7.4
5fb29d