mirror of
https://git.busybox.net/busybox
synced 2026-02-07 20:50:26 +00:00
libbb: introduce and use xasprintf_inplace()
function old new delta xasprintf_and_free - 49 +49 watch_main 269 282 +13 singlemount 1313 1315 +2 append_mount_options 157 149 -8 ip_port_str 122 112 -10 lsblk_main 869 858 -11 add_cmd 1178 1167 -11 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/4 up/down: 64/-40) Total: 24 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
3d572a8cc3
commit
fddd93edbd
9 changed files with 48 additions and 34 deletions
|
|
@ -657,9 +657,8 @@ static void add_cmd(const char *cmdstr)
|
|||
|
||||
/* Append this line to any unfinished line from last time. */
|
||||
if (G.add_cmd_line) {
|
||||
char *tp = xasprintf("%s\n%s", G.add_cmd_line, cmdstr);
|
||||
free(G.add_cmd_line);
|
||||
cmdstr = G.add_cmd_line = tp;
|
||||
cmdstr = xasprintf_inplace(G.add_cmd_line,
|
||||
"%s\n%s", G.add_cmd_line, cmdstr);
|
||||
}
|
||||
|
||||
/* If this line ends with unescaped backslash, request next line. */
|
||||
|
|
|
|||
|
|
@ -950,6 +950,8 @@ int bb_putchar(int ch) FAST_FUNC;
|
|||
int bb_putchar_stderr(char ch) FAST_FUNC;
|
||||
int fputs_stdout(const char *s) FAST_FUNC;
|
||||
char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
|
||||
char *xasprintf_and_free(char *allocated, const char *format, ...) __attribute__ ((format(printf, 2, 3))) FAST_FUNC RETURNS_MALLOC;
|
||||
#define xasprintf_inplace(allocated, ...) ((allocated) = xasprintf_and_free((allocated), __VA_ARGS__))
|
||||
char *auto_string(char *str) FAST_FUNC;
|
||||
// gcc-4.1.1 still isn't good enough at optimizing it
|
||||
// (+200 bytes compared to macro)
|
||||
|
|
|
|||
|
|
@ -349,6 +349,22 @@ char* FAST_FUNC xasprintf(const char *format, ...)
|
|||
return string_ptr;
|
||||
}
|
||||
|
||||
char* FAST_FUNC xasprintf_and_free(char *allocated, const char *format, ...)
|
||||
{
|
||||
va_list p;
|
||||
int r;
|
||||
char *string_ptr;
|
||||
|
||||
va_start(p, format);
|
||||
r = vasprintf(&string_ptr, format, p);
|
||||
va_end(p);
|
||||
|
||||
if (r < 0)
|
||||
bb_die_memory_exhausted();
|
||||
free(allocated);
|
||||
return string_ptr;
|
||||
}
|
||||
|
||||
void FAST_FUNC xsetenv(const char *key, const char *value)
|
||||
{
|
||||
if (setenv(key, value, 1))
|
||||
|
|
|
|||
|
|
@ -1010,9 +1010,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
|
|||
char **arg = argv;
|
||||
while (*++arg) {
|
||||
/* Enclose options in quotes */
|
||||
char *s = options;
|
||||
options = xasprintf("%s \"%s\"", s ? s : "", *arg);
|
||||
free(s);
|
||||
xasprintf_inplace(options, "%s \"%s\"", options ? options : "", *arg);
|
||||
*arg = NULL;
|
||||
}
|
||||
# else
|
||||
|
|
|
|||
|
|
@ -895,16 +895,15 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in
|
|||
while ((buf = xmalloc_fgetline(f)) != NULL) {
|
||||
#if ENABLE_DESKTOP
|
||||
/* Trailing "\" concatenates lines */
|
||||
//TODO: check how to handle "line\\" (double backslashes)
|
||||
char *p;
|
||||
while ((p = last_char_is(buf, '\\')) != NULL) {
|
||||
*p = '\0';
|
||||
rest_of_line = xmalloc_fgetline(f);
|
||||
if (!rest_of_line)
|
||||
break;
|
||||
p = xasprintf("%s%s", buf, rest_of_line);
|
||||
free(buf);
|
||||
xasprintf_inplace(buf, "%s%s", buf, rest_of_line);
|
||||
free(rest_of_line);
|
||||
buf = p;
|
||||
}
|
||||
#endif
|
||||
rest_of_line = buf;
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ static const char *get_sname(int port, const char *proto, int numeric)
|
|||
|
||||
static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int numeric)
|
||||
{
|
||||
char *host, *host_port;
|
||||
char *host;
|
||||
|
||||
/* Code which used "*" for INADDR_ANY is removed: it's ambiguous
|
||||
* in IPv6, while "0.0.0.0" is not. */
|
||||
|
|
@ -402,9 +402,8 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int
|
|||
if (!host)
|
||||
host = xmalloc_sockaddr2dotted_noport(addr);
|
||||
|
||||
host_port = xasprintf("%s:%s", host, get_sname(htons(port), proto, numeric));
|
||||
free(host);
|
||||
return host_port;
|
||||
xasprintf_inplace(host, "%s:%s", host, get_sname(htons(port), proto, numeric));
|
||||
return host;
|
||||
}
|
||||
|
||||
struct inet_params {
|
||||
|
|
|
|||
|
|
@ -76,12 +76,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
|
|||
// watch ls -l "a /tmp" "2>&1" - ls won't see "a /tmp" as one param.
|
||||
argv0 = argv;
|
||||
// If -x, cmd is only used for printing header
|
||||
cmd = *argv;
|
||||
cmd = xstrdup(*argv);
|
||||
while (*++argv)
|
||||
cmd = xasprintf("%s %s", cmd, *argv);
|
||||
//leaks cmd ^^^
|
||||
//TODO: create and use xasprintf_inplace(DST, fmt, args_one_of_which_is_DST)
|
||||
//which frees old DST?
|
||||
xasprintf_inplace(cmd, "%s %s", cmd, *argv);
|
||||
if (opt & (1 << 3))
|
||||
argv = argv0; // If -x, restore argv[0] to !NULL
|
||||
|
||||
|
|
|
|||
|
|
@ -101,10 +101,10 @@ static char *get_mountpoints(const char *majmin)
|
|||
|
||||
mountpoints = NULL;
|
||||
len = strlen(majmin);
|
||||
p = G.mountinfo; // "/proc/self/mountinfo"
|
||||
p = G.mountinfo; // contents of "/proc/self/mountinfo"
|
||||
/* lines a-la "63 1 259:3 / /MNTPOINT per-mount_options - ext4 /dev/NAME per-superblock_options" */
|
||||
while (*p) {
|
||||
char *e, *f;
|
||||
char *e;
|
||||
|
||||
p = skip_non_whitespace(p);
|
||||
if (*p != ' ') break;
|
||||
|
|
@ -127,12 +127,11 @@ static char *get_mountpoints(const char *majmin)
|
|||
// at " /MNTPOINT"
|
||||
e = skip_non_whitespace(p + 1);
|
||||
// e is at the end of " /MNTPOINT"
|
||||
f = mountpoints;
|
||||
// NO. We return " /MNT1 /MNT2 /MNT3" _with_ leading space!
|
||||
// if (!f)
|
||||
// if (!mountpoints)
|
||||
// p++;
|
||||
mountpoints = xasprintf("%s%.*s", f ? f : "", (int)(e - p), p);
|
||||
free(f);
|
||||
xasprintf_inplace(mountpoints, "%s%.*s",
|
||||
mountpoints ? mountpoints : "", (int)(e - p), p);
|
||||
}
|
||||
return mountpoints;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -556,27 +556,33 @@ static int verbose_mount(const char *source, const char *target,
|
|||
#endif
|
||||
|
||||
// Append mount options to string
|
||||
// ("merge two comma-separated lists" is a good candidate for libbb!)
|
||||
static void append_mount_options(char **oldopts, const char *newopts)
|
||||
{
|
||||
if (*oldopts && **oldopts) {
|
||||
//TODO: do this unconditionally?
|
||||
//this way, newopts of "opt1,opt2,opt1"
|
||||
//will be de-duped into "opt1,opt2" in _both_ cases
|
||||
//(whether or now old opts are empty)
|
||||
//the only modification needed is to not prepend extra comma
|
||||
//when old opts is "".
|
||||
// Do not insert options which are already there
|
||||
while (newopts[0]) {
|
||||
while (*newopts) {
|
||||
char *p;
|
||||
int len;
|
||||
|
||||
//if (*newopts == ',') { newopts++; continue; }
|
||||
len = strchrnul(newopts, ',') - newopts;
|
||||
p = *oldopts;
|
||||
while (1) {
|
||||
if (!strncmp(p, newopts, len)
|
||||
if (strncmp(p, newopts, len) == 0
|
||||
&& (p[len] == ',' || p[len] == '\0'))
|
||||
goto skip;
|
||||
p = strchr(p,',');
|
||||
p = strchr(p, ',');
|
||||
if (!p) break;
|
||||
p++;
|
||||
}
|
||||
p = xasprintf("%s,%.*s", *oldopts, len, newopts);
|
||||
free(*oldopts);
|
||||
*oldopts = p;
|
||||
xasprintf_inplace(*oldopts, "%s,%.*s", *oldopts, len, newopts);
|
||||
skip:
|
||||
newopts += len;
|
||||
while (*newopts == ',') newopts++;
|
||||
|
|
@ -2065,12 +2071,11 @@ static int singlemount(struct mntent *mp, int ignore_busy)
|
|||
if (!is_prefixed_with(filteropts, ",ip="+1)
|
||||
&& !strstr(filteropts, ",ip=")
|
||||
) {
|
||||
char *dotted, *ip;
|
||||
char *ip;
|
||||
// Insert "ip=..." option into options
|
||||
dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
|
||||
ip = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
|
||||
if (ENABLE_FEATURE_CLEAN_UP) free(lsa);
|
||||
ip = xasprintf("ip=%s", dotted);
|
||||
if (ENABLE_FEATURE_CLEAN_UP) free(dotted);
|
||||
xasprintf_inplace(ip, "ip=%s", ip);
|
||||
// Note: IPv6 scoped addresses ("host%iface", see RFC 4007) should be
|
||||
// handled by libc in getnameinfo() (inside xmalloc_sockaddr2dotted_noport()).
|
||||
// Currently, glibc does not support that (has no NI_NUMERICSCOPE),
|
||||
|
|
|
|||
Loading…
Reference in a new issue