Back in 2007, bb_simple_perror_msg() was introduced to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space because it avoids the overhead of a
call to a variadic function. However there has never been a simple
version of bb_error_msg(), and since that time various new calls to
bb_perror_msg() have been added that only take a single parameter and so
could have been using bb_simple_perror_message().
This changeset introduces 'simple' versions of bb_error_msg(),
bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and
also overrides the standard versions with macros that use some
preprocessor magic to automatically substitute any calls that only take
a single parameter with the corresponding 'simple' version.
All calls to the standard functions in the codebase that pass something
like ("%s", arg) as the parameters have been replaced with 'simple'
calls, as the macros can't fix these up.
The space saving gained by this (using 'defconfig' on x86_64 with gcc
Ubuntu 6.4.0-17ubuntu1~16.04) was:
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 4/301 up/down: 73/-910) Total: -837
bytes
text data bss dec hex filename
936949 4263 1856 943068 e63dc busybox_old
936098 4263 1856 942217 e6089 busybox_unstripped
Signed-off-by: James Byrne <[email protected]>
---
include/libbb.h | 19 +++++++++++++++++++
libbb/herror_msg.c | 10 ++++++++++
libbb/verror_msg.c | 10 ++++++++++
libbb/xgethostbyname.c | 2 +-
miscutils/chat.c | 2 +-
networking/arp.c | 10 +++++-----
networking/tftp.c | 2 +-
networking/wget.c | 2 +-
shell/hush.c | 2 +-
util-linux/acpid.c | 2 +-
util-linux/fsck_minix.c | 2 +-
util-linux/mount.c | 4 ++--
12 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/include/libbb.h b/include/libbb.h
index a605c7f..23ad68d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1286,19 +1286,38 @@ extern void (*die_func)(void);
void xfunc_die(void) NORETURN FAST_FUNC;
void bb_show_usage(void) NORETURN FAST_FUNC;
void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)))
FAST_FUNC;
+void bb_simple_error_msg(const char *s) FAST_FUNC;
void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format
(printf, 1, 2))) FAST_FUNC;
+void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC;
void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)))
FAST_FUNC;
void bb_simple_perror_msg(const char *s) FAST_FUNC;
void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn,
format (printf, 1, 2))) FAST_FUNC;
void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)))
FAST_FUNC;
+void bb_simple_herror_msg(const char *s) NORETURN FAST_FUNC;
void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn,
format (printf, 1, 2))) FAST_FUNC;
+void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
void bb_perror_nomsg(void) FAST_FUNC;
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;
+/* Override bb_error_msg() and related functions with macros that will
+ * substitute them for the equivalent bb_simple_error_msg() function when
+ * they are used with only a single parameter. Macro approach inspired by
+ * https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments and
+ * https://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99
+ */
+#define _ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13,
_14, _15, ...) _15
+#define BB_MSG_KIND(...) _ARG16(__VA_ARGS__, , , , , , , , , , , , , , ,
_simple)
+#define _BB_MSG(name, kind, ...) bb##kind##name(__VA_ARGS__)
+#define BB_MSG(name, kind, ...) _BB_MSG(name, kind, __VA_ARGS__)
+#define bb_error_msg(...) BB_MSG(_error_msg, BB_MSG_KIND(__VA_ARGS__),
__VA_ARGS__)
+#define bb_error_msg_and_die(...) BB_MSG(_error_msg_and_die,
BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
+#define bb_perror_msg(...) BB_MSG(_perror_msg, BB_MSG_KIND(__VA_ARGS__),
__VA_ARGS__)
+#define bb_perror_msg_and_die(...) BB_MSG(_perror_msg_and_die,
BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
+
/* We need to export XXX_main from libbusybox
* only if we build "individual" binaries
*/
diff --git a/libbb/herror_msg.c b/libbb/herror_msg.c
index d041076..a7dd986 100644
--- a/libbb/herror_msg.c
+++ b/libbb/herror_msg.c
@@ -26,3 +26,13 @@ void FAST_FUNC bb_herror_msg_and_die(const char *s, ...)
va_end(p);
xfunc_die();
}
+
+void FAST_FUNC bb_simple_herror_msg(const char *s)
+{
+ bb_herror_msg("%s", s);
+}
+
+void FAST_FUNC bb_simple_herror_msg_and_die(const char *s)
+{
+ bb_herror_msg_and_die("%s", s);
+}
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c
index 22c3035..155b28c 100644
--- a/libbb/verror_msg.c
+++ b/libbb/verror_msg.c
@@ -180,3 +180,13 @@ void FAST_FUNC bb_error_msg(const char *s, ...)
bb_verror_msg(s, p, NULL);
va_end(p);
}
+
+void FAST_FUNC bb_simple_error_msg(const char *s)
+{
+ bb_error_msg("%s", s);
+}
+
+void FAST_FUNC bb_simple_error_msg_and_die(const char *s)
+{
+ bb_error_msg_and_die("%s", s);
+}
diff --git a/libbb/xgethostbyname.c b/libbb/xgethostbyname.c
index 89d0329..9446dab 100644
--- a/libbb/xgethostbyname.c
+++ b/libbb/xgethostbyname.c
@@ -12,6 +12,6 @@ struct hostent* FAST_FUNC xgethostbyname(const char *name)
{
struct hostent *retval = gethostbyname(name);
if (!retval)
- bb_herror_msg_and_die("%s", name);
+ bb_simple_herror_msg_and_die(name);
return retval;
}
diff --git a/miscutils/chat.c b/miscutils/chat.c
index 2dfe52c..574d514 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -307,7 +307,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv)
} else if (DIR_SAY == key) {
// just print argument verbatim
// TODO: should we use full_write() to avoid
unistd/stdio conflict?
- bb_error_msg("%s", arg);
+ bb_simple_error_msg(arg);
}
// next, please!
argv++;
diff --git a/networking/arp.c b/networking/arp.c
index 177ab15..0fe4409 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -116,7 +116,7 @@ static int arp_del(char **args)
/* Resolve the host name. */
host = *args;
if (ap->input(host, &sa) < 0) {
- bb_herror_msg_and_die("%s", host);
+ bb_simple_herror_msg_and_die(host);
}
/* If a host has more than one address, use the correct one! */
@@ -173,7 +173,7 @@ static int arp_del(char **args)
if (strcmp(*args, "255.255.255.255") != 0) {
host = *args;
if (ap->input(host, &sa) < 0) {
- bb_herror_msg_and_die("%s", host);
+ bb_simple_herror_msg_and_die(host);
}
memcpy(&req.arp_netmask, &sa, sizeof(struct
sockaddr));
req.arp_flags |= ATF_NETMASK;
@@ -261,7 +261,7 @@ static int arp_set(char **args)
host = *args++;
if (ap->input(host, &sa) < 0) {
- bb_herror_msg_and_die("%s", host);
+ bb_simple_herror_msg_and_die(host);
}
/* If a host has more than one address, use the correct one! */
memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
@@ -326,7 +326,7 @@ static int arp_set(char **args)
if (strcmp(*args, "255.255.255.255") != 0) {
host = *args;
if (ap->input(host, &sa) < 0) {
- bb_herror_msg_and_die("%s", host);
+ bb_simple_herror_msg_and_die(host);
}
memcpy(&req.arp_netmask, &sa, sizeof(struct
sockaddr));
flags |= ATF_NETMASK;
@@ -422,7 +422,7 @@ static int arp_show(char *name)
if (name != NULL) {
/* Resolve the host name. */
if (ap->input(name, &sa) < 0) {
- bb_herror_msg_and_die("%s", name);
+ bb_simple_herror_msg_and_die(name);
}
host = xstrdup(ap->sprint(&sa, 1));
}
diff --git a/networking/tftp.c b/networking/tftp.c
index 4cd3918..0f56380 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -736,7 +736,7 @@ static int tftp_protocol(
strcpy(G_error_pkt_str, bb_msg_read_error);
send_err_pkt:
if (G_error_pkt_str[0])
- bb_error_msg("%s", G_error_pkt_str);
+ bb_simple_error_msg(G_error_pkt_str);
G.error_pkt[1] = TFTP_ERROR;
xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str),
&peer_lsa->u.sa, peer_lsa->len);
diff --git a/networking/wget.c b/networking/wget.c
index 30c3392..80683f6 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -772,7 +772,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct
host_info *target, len_and_
#endif
if (ftpcmd(NULL, NULL, sfp) != 220)
- bb_error_msg_and_die("%s", G.wget_buf);
+ bb_simple_error_msg_and_die(G.wget_buf);
/* note: ftpcmd() sanitizes G.wget_buf, ok to print */
/* Split username:password pair */
diff --git a/shell/hush.c b/shell/hush.c
index c777001..a5e1745 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -9998,7 +9998,7 @@ static int FAST_FUNC builtin_read(char **argv)
}
if ((uintptr_t)r > 1) {
- bb_error_msg("%s", r);
+ bb_simple_error_msg(r);
r = (char*)(uintptr_t)1;
}
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 4f491fa..eded6b0 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -148,7 +148,7 @@ static void process_event(const char *event)
const char *args[] = { "run-parts", handler, NULL };
// log the event
- bb_error_msg("%s", event);
+ bb_simple_error_msg(event);
// spawn handler
// N.B. run-parts would require scripts to have #!/bin/sh
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index c4612f2..fc9aecc 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -321,7 +321,7 @@ static void die(const char *str)
{
if (termios_set)
tcsetattr_stdin_TCSANOW(&sv_termios);
- bb_error_msg_and_die("%s", str);
+ bb_simple_error_msg_and_die(str);
}
static void push_filename(const char *name)
diff --git a/util-linux/mount.c b/util-linux/mount.c
index fa2e7b1..41ce2fb 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1292,7 +1292,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned
long vfsflags, char *fi
if (!inet_aton(hostname, &server_addr.sin_addr)) {
hp = gethostbyname(hostname);
if (hp == NULL) {
- bb_herror_msg("%s", hostname);
+ bb_simple_herror_msg(hostname);
goto fail;
}
if (hp->h_length != (int)sizeof(struct in_addr)) {
@@ -1587,7 +1587,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned
long vfsflags, char *fi
} else {
hp = gethostbyname(mounthost);
if (hp == NULL) {
- bb_herror_msg("%s", mounthost);
+ bb_simple_herror_msg(mounthost);
goto fail;
}
if (hp->h_length != (int)sizeof(struct in_addr)) {
--
2.7.4
The contents of this email and any attachment are confidential to the intended
recipient(s). If you are not an intended recipient: (i) do not use, disclose,
distribute, copy or publish this email or its contents; (ii) please contact the
sender immediately; and (iii) delete this email. Origami Energy Limited
(company number 8619644); Origami Storage Limited (company number 10436515) and
OSSPV001 Limited (company number 10933403), each registered in England and each
with a registered office at: Ashcombe Court, Woolsack Way, Godalming, GU7 1LQ.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox