From c484846c4459affa769b84cbd0b586f2bbaec828 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 17 Jul 2023 17:29:36 +0200
Subject: [PATCH] introduce and use exitcode_t

function                                             old     new   delta
strings_main                                         422     420      -2
setfattr_main                                        175     173      -2
brctl_main                                          1548    1546      -2
makedevs_main                                        979     975      -4
rev_main                                             337     332      -5
getfattr_main                                        307     302      -5
cut_main                                            1201    1196      -5
cksum_main                                           398     393      -5
umount_main                                          573     565      -8
ln_main                                              516     508      -8
expand_main                                          660     652      -8
df_main                                             1068    1060      -8
renice_main                                          346     332     -14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/13 up/down: 0/-76)            Total: -76 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 coreutils/cksum.c    | 2 +-
 coreutils/cut.c      | 2 +-
 coreutils/dd.c       | 2 +-
 coreutils/df.c       | 2 +-
 coreutils/expand.c   | 2 +-
 coreutils/fold.c     | 2 +-
 coreutils/ln.c       | 2 +-
 coreutils/touch.c    | 2 +-
 include/libbb.h      | 7 +++++++
 miscutils/getfattr.c | 2 +-
 miscutils/makedevs.c | 2 +-
 miscutils/setfattr.c | 2 +-
 miscutils/strings.c  | 3 ++-
 networking/brctl.c   | 2 +-
 networking/tc.c      | 5 ++---
 util-linux/renice.c  | 2 +-
 util-linux/rev.c     | 2 +-
 util-linux/umount.c  | 2 +-
 18 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/coreutils/cksum.c b/coreutils/cksum.c
index badc63a6a..1fb6ef2d0 100644
--- a/coreutils/cksum.c
+++ b/coreutils/cksum.c
@@ -39,7 +39,7 @@ int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int cksum_main(int argc UNUSED_PARAM, char **argv)
 {
 	uint32_t *crc32_table = crc32_filltable(NULL, IS_CKSUM);
-	int exit_code = EXIT_SUCCESS;
+	exitcode_t exit_code = EXIT_SUCCESS;
 
 #if ENABLE_DESKTOP
 	getopt32(argv, ""); /* cksum coreutils 6.9 compat */
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 25b16d1a8..d129f9b9d 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -311,7 +311,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
 	}
 
 	{
-		int retval = EXIT_SUCCESS;
+		exitcode_t retval = EXIT_SUCCESS;
 
 		if (!*argv)
 			*--argv = (char *)"-";
diff --git a/coreutils/dd.c b/coreutils/dd.c
index c032ebe1b..8bb782781 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -375,7 +375,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 		OP_oflag_direct,
 #endif
 	};
-	smallint exitcode = EXIT_FAILURE;
+	exitcode_t exitcode = EXIT_FAILURE;
 	int i;
 	size_t ibs = 512;
 	char *ibuf;
diff --git a/coreutils/df.c b/coreutils/df.c
index 76e9cefbf..03aa78148 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -113,7 +113,7 @@ int df_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int df_main(int argc UNUSED_PARAM, char **argv)
 {
 	unsigned long df_disp_hr = 1024;
-	int status = EXIT_SUCCESS;
+	exitcode_t status = EXIT_SUCCESS;
 	unsigned opt;
 	FILE *mount_table;
 	struct mntent *mount_entry;
diff --git a/coreutils/expand.c b/coreutils/expand.c
index 47693e144..c4db26055 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -192,7 +192,7 @@ int expand_main(int argc UNUSED_PARAM, char **argv)
 	FILE *file;
 	unsigned tab_size;
 	unsigned opt;
-	int exit_status = EXIT_SUCCESS;
+	exitcode_t exit_status = EXIT_SUCCESS;
 
 	init_unicode();
 
diff --git a/coreutils/fold.c b/coreutils/fold.c
index 2839c8c68..8112fe911 100644
--- a/coreutils/fold.c
+++ b/coreutils/fold.c
@@ -77,7 +77,7 @@ int fold_main(int argc UNUSED_PARAM, char **argv)
 	char *line_out = NULL;
 	const char *w_opt = "80";
 	unsigned width;
-	smallint exitcode = EXIT_SUCCESS;
+	exitcode_t exitcode = EXIT_SUCCESS;
 
 	init_unicode();
 
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 34eec398a..080ba142e 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -52,7 +52,7 @@
 int ln_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int ln_main(int argc, char **argv)
 {
-	int status = EXIT_SUCCESS;
+	exitcode_t status = EXIT_SUCCESS;
 	int opts;
 	char *last;
 	char *src_name;
diff --git a/coreutils/touch.c b/coreutils/touch.c
index 8fde70e12..ced596c89 100644
--- a/coreutils/touch.c
+++ b/coreutils/touch.c
@@ -77,7 +77,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
 {
 	int fd;
 	int opts;
-	smalluint status = EXIT_SUCCESS;
+	exitcode_t status = EXIT_SUCCESS;
 #if ENABLE_FEATURE_TOUCH_SUSV3
 	char *reference_file;
 	char *date_str;
diff --git a/include/libbb.h b/include/libbb.h
index 640fa3988..eb97a9880 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1444,6 +1444,13 @@ void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
 void bb_die_memory_exhausted(void) NORETURN FAST_FUNC;
 void bb_logenv_override(void) FAST_FUNC;
 
+/* x86 benefits from narrow exit code variables
+ * (because it has no widening MOV imm8,word32 insn, has to use MOV imm32,w
+ * for "exitcode = EXIT_FAILURE" and similar. The downside is that sometimes
+*  gcc widens the variable to int in various ugly suboptimal ways).
+ */
+typedef smalluint exitcode_t;
+
 #if ENABLE_FEATURE_SYSLOG_INFO
 void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
 void bb_simple_info_msg(const char *s) FAST_FUNC;
diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c
index 905aec65f..cb42fdac0 100644
--- a/miscutils/getfattr.c
+++ b/miscutils/getfattr.c
@@ -77,7 +77,7 @@ int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int getfattr_main(int argc UNUSED_PARAM, char **argv)
 {
 	const char *name;
-	int status;
+	exitcode_t status;
 	int opt;
 	char *buf = NULL;
 	size_t bufsize = 0;
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index 48be91875..999a3b976 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -181,7 +181,7 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv)
 {
 	parser_t *parser;
 	char *line = (char *)"-";
-	int ret = EXIT_SUCCESS;
+	exitcode_t ret = EXIT_SUCCESS;
 
 	getopt32(argv, "^" "d:" "\0" "=1", &line);
 	argv += optind;
diff --git a/miscutils/setfattr.c b/miscutils/setfattr.c
index 10d1840c9..b68bc9452 100644
--- a/miscutils/setfattr.c
+++ b/miscutils/setfattr.c
@@ -32,7 +32,7 @@ int setfattr_main(int argc UNUSED_PARAM, char **argv)
 {
 	const char *name;
 	const char *value = "";
-	int status;
+	exitcode_t status;
 	int opt;
 	enum {
 		OPT_h = (1 << 0),
diff --git a/miscutils/strings.c b/miscutils/strings.c
index 036df5c5d..bd1850cbb 100644
--- a/miscutils/strings.c
+++ b/miscutils/strings.c
@@ -40,7 +40,8 @@
 int strings_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int strings_main(int argc UNUSED_PARAM, char **argv)
 {
-	int n, c, status = EXIT_SUCCESS;
+	int n, c;
+	exitcode_t status = EXIT_SUCCESS;
 	unsigned count;
 	off_t offset;
 	FILE *file;
diff --git a/networking/brctl.c b/networking/brctl.c
index 7b0270b51..0f8dc2f7a 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -538,7 +538,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
 		DIR *net;
 		struct dirent *ent;
 		int need_hdr = 1;
-		int exitcode = EXIT_SUCCESS;
+		exitcode_t exitcode = EXIT_SUCCESS;
 
 		if (*argv) {
 			/* "show BR1 BR2 BR3" */
diff --git a/networking/tc.c b/networking/tc.c
index 43187f7ee..3a79fd2d9 100644
--- a/networking/tc.c
+++ b/networking/tc.c
@@ -502,7 +502,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
 	};
 	struct rtnl_handle rth;
 	struct tcmsg msg;
-	int ret, obj, cmd, arg;
+	int obj, cmd, arg;
 	char *dev = NULL;
 
 	INIT_G();
@@ -510,7 +510,6 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
 	if (!*++argv)
 		bb_show_usage();
 	xrtnl_open(&rth);
-	ret = EXIT_SUCCESS;
 
 	obj = index_in_substrings(objects, *argv++);
 	if (obj < 0)
@@ -625,5 +624,5 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
 	if (ENABLE_FEATURE_CLEAN_UP) {
 		rtnl_close(&rth);
 	}
-	return ret;
+	return EXIT_SUCCESS;
 }
diff --git a/util-linux/renice.c b/util-linux/renice.c
index 53f197cce..f2737f29b 100644
--- a/util-linux/renice.c
+++ b/util-linux/renice.c
@@ -45,7 +45,7 @@ int renice_main(int argc UNUSED_PARAM, char **argv)
 {
 	static const char Xetpriority_msg[] ALIGN1 = "%cetpriority";
 
-	int retval = EXIT_SUCCESS;
+	exitcode_t retval = EXIT_SUCCESS;
 	int which = PRIO_PROCESS;  /* Default 'which' value. */
 	int use_relative = 0;
 	int adjustment, new_priority;
diff --git a/util-linux/rev.c b/util-linux/rev.c
index 12df2b9ff..aad53722d 100644
--- a/util-linux/rev.c
+++ b/util-linux/rev.c
@@ -51,7 +51,7 @@ static void strrev(CHAR_T *s, int len)
 int rev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int rev_main(int argc UNUSED_PARAM, char **argv)
 {
-	int retval;
+	exitcode_t retval;
 	size_t bufsize;
 	char *buf;
 
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 23da32868..f5c97a034 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -97,7 +97,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv)
 	struct mntent me;
 	FILE *fp;
 	char *fstype = NULL;
-	int status = EXIT_SUCCESS;
+	exitcode_t status = EXIT_SUCCESS;
 	unsigned opt;
 	struct mtab_list {
 		char *dir;