aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--Makefile.flags2
-rw-r--r--applets/individual.c2
-rw-r--r--applets/usage_pod.c2
-rw-r--r--archival/libarchive/data_extract_all.c4
-rw-r--r--coreutils/cat.c4
-rw-r--r--coreutils/cut.c2
-rw-r--r--coreutils/expand.c2
-rw-r--r--coreutils/head.c2
-rw-r--r--coreutils/id.c2
-rw-r--r--coreutils/ls.c2
-rw-r--r--coreutils/mknod.c4
-rw-r--r--coreutils/nl.c2
-rw-r--r--coreutils/od_bloaty.c26
-rw-r--r--coreutils/paste.c4
-rw-r--r--coreutils/stat.c2
-rw-r--r--coreutils/stty.c2
-rw-r--r--coreutils/uudecode.c2
-rw-r--r--coreutils/yes.c2
-rw-r--r--editors/awk.c18
-rw-r--r--editors/ed.c2
-rw-r--r--editors/vi.c17
-rw-r--r--include/libbb.h8
-rw-r--r--include/platform.h2
-rw-r--r--init/bootchartd.c10
-rw-r--r--klibc-utils/nuke.c2
-rw-r--r--libbb/appletlib.c96
-rw-r--r--libbb/bb_askpass.c2
-rw-r--r--libbb/compare_string_array.c14
-rw-r--r--libbb/dump.c2
-rw-r--r--libbb/fgets_str.c17
-rw-r--r--libbb/lineedit.c8
-rw-r--r--libbb/login.c6
-rw-r--r--libbb/print_numbered_lines.c5
-rw-r--r--libbb/procps.c45
-rw-r--r--libbb/pw_encrypt.c4
-rw-r--r--libbb/time.c6
-rw-r--r--libbb/update_passwd.c2
-rw-r--r--libbb/xfuncs_printf.c16
-rw-r--r--loginutils/cryptpw.c6
-rw-r--r--mailutils/mail.c15
-rw-r--r--miscutils/bc.c64
-rw-r--r--miscutils/conspy.c4
-rw-r--r--miscutils/i2c_tools.c6
-rw-r--r--miscutils/strings.c2
-rw-r--r--miscutils/ts.c4
-rw-r--r--networking/brctl.c2
-rw-r--r--networking/httpd.c15
-rw-r--r--networking/inetd.c2
-rw-r--r--networking/libiproute/ipaddress.c14
-rw-r--r--networking/libiproute/iprule.c7
-rw-r--r--networking/nslookup.c30
-rw-r--r--networking/ntpd.c11
-rw-r--r--networking/ping.c38
-rw-r--r--networking/tls_fe.c28
-rw-r--r--networking/traceroute.c15
-rw-r--r--networking/udhcp/Config.src8
-rw-r--r--networking/udhcp/d6_dhcpc.c4
-rw-r--r--networking/udhcp/dhcpc.c4
-rw-r--r--networking/udhcp/dumpleases.c2
-rw-r--r--procps/nmeter.c8
-rw-r--r--procps/pmap.c12
-rw-r--r--procps/powertop.c2
-rw-r--r--procps/top.c2
-rw-r--r--runit/runsv.c4
-rw-r--r--runit/svlogd.c4
-rwxr-xr-xscripts/bb_release1
-rw-r--r--shell/ash.c36
-rw-r--r--shell/ash_test/ash-vars/var_bash_repl_empty_var.right1
-rwxr-xr-xshell/ash_test/ash-vars/var_bash_repl_empty_var.tests2
-rw-r--r--shell/hush.c24
-rw-r--r--sysklogd/klogd.c2
-rw-r--r--sysklogd/logread.c4
-rw-r--r--sysklogd/syslogd.c2
-rwxr-xr-xtestsuite/awk.tests5
-rwxr-xr-xtestsuite/cat.tests24
-rw-r--r--testsuite/dc_add_results.txt36
-rw-r--r--testsuite/dc_decimal_results.txt42
-rw-r--r--testsuite/dc_divmod_results.txt8
-rw-r--r--testsuite/dc_multiply_results.txt4
-rw-r--r--testsuite/dc_power_results.txt72
-rw-r--r--testsuite/dc_subtract_results.txt14
-rwxr-xr-xtestsuite/nl.tests39
-rw-r--r--util-linux/fdisk_gpt.c4
-rw-r--r--util-linux/hwclock.c8
-rw-r--r--util-linux/mdev.c2
-rw-r--r--util-linux/rev.c2
-rw-r--r--util-linux/script.c2
88 files changed, 569 insertions, 432 deletions
diff --git a/Makefile b/Makefile
index cc6112a1b..17f55dce2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 1
-PATCHLEVEL = 33
+PATCHLEVEL = 34
SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = .git
NAME = Unnamed
# *DOCUMENTATION*
diff --git a/Makefile.flags b/Makefile.flags
index 6ff4d7239..7a445c3b5 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -181,8 +181,10 @@ LDLIBS += $(if $(SELINUX_LIBS),$(SELINUX_LIBS:-l%=%),$(SELINUX_PC_MODULES:lib%=%
endif
ifeq ($(CONFIG_FEATURE_NSLOOKUP_BIG),y)
+ifneq (,$(findstring linux,$(shell $(CC) $(CFLAGS) -dumpmachine)))
LDLIBS += resolv
endif
+endif
ifeq ($(CONFIG_EFENCE),y)
LDLIBS += efence
diff --git a/applets/individual.c b/applets/individual.c
index 4c468df06..e94f26c93 100644
--- a/applets/individual.c
+++ b/applets/individual.c
@@ -19,6 +19,6 @@ int main(int argc, char **argv)
void bb_show_usage(void)
{
- fputs(APPLET_full_usage "\n", stdout);
+ fputs_stdout(APPLET_full_usage "\n");
exit(EXIT_FAILURE);
}
diff --git a/applets/usage_pod.c b/applets/usage_pod.c
index ccc166aed..9e6d3f0ee 100644
--- a/applets/usage_pod.c
+++ b/applets/usage_pod.c
@@ -71,7 +71,7 @@ int main(void)
} else {
printf(", ");
}
- printf(usage_array[i].aname);
+ printf("%s", usage_array[i].aname);
col += len2;
}
printf("\n\n");
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 3142405a3..049c2c156 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -159,6 +159,10 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
break;
}
case S_IFDIR:
+//TODO: this causes problems if tarball contains a r-xr-xr-x directory:
+// we create this directory, and then fail to create files inside it
+// (if tar xf isn't run as root).
+// GNU tar works around this by chmod-ing directories *after* all files are extracted.
res = mkdir(dst_name, file_header->mode);
if ((res != 0)
&& (errno != EISDIR) /* btw, Linux doesn't return this */
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 65f0648f9..4b3414941 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -152,7 +152,7 @@ static int catv(unsigned opts, char **argv)
eol_seen = (c == eol_char);
#endif
visible(c, buf, opts);
- fputs(buf, stdout);
+ fputs_stdout(buf);
}
}
if (ENABLE_FEATURE_CLEAN_UP && fd)
@@ -201,7 +201,7 @@ int cat_main(int argc UNUSED_PARAM, char **argv)
ns.start = 1;
ns.inc = 1;
ns.sep = "\t";
- ns.empty_str = "\n";
+ ns.empty_str = NULL;
ns.all = !(opts & CAT_OPT_b); /* -n without -b */
ns.nonempty = (opts & CAT_OPT_b); /* -b (with or without -n) */
exitcode = EXIT_SUCCESS;
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 1acbb513e..16418ff33 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -167,7 +167,7 @@ static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, u
* printed */
if (nfields_printed > 0)
putchar(delim);
- fputs(field, stdout);
+ fputs_stdout(field);
printed[ndelim] = 'X';
nfields_printed++; /* shouldn't overflow.. */
}
diff --git a/coreutils/expand.c b/coreutils/expand.c
index 5f5993921..c5e1de6f5 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -123,7 +123,7 @@ static void expand(FILE *file, unsigned tab_size, unsigned opt)
}
ptr++;
}
- fputs(ptr_strbeg, stdout);
+ fputs_stdout(ptr_strbeg);
free(line);
}
}
diff --git a/coreutils/head.c b/coreutils/head.c
index 1219dfe8b..b6efabbe0 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -117,7 +117,7 @@ print_except_N_last_lines(FILE *fp, unsigned count)
char *c;
if (head == count)
head = 0;
- fputs(circle[head], stdout);
+ fputs_stdout(circle[head]);
c = xmalloc_fgets(fp);
if (!c)
goto ret;
diff --git a/coreutils/id.c b/coreutils/id.c
index 78d5f2a50..f453a87ae 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -258,7 +258,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
bb_error_msg_and_die("can't get process context%s",
username ? " for a different user" : "");
}
- fputs(scontext, stdout);
+ fputs_stdout(scontext);
}
/* freecon(NULL) seems to be harmless */
if (ENABLE_FEATURE_CLEAN_UP)
diff --git a/coreutils/ls.c b/coreutils/ls.c
index e5375a61a..80ef92079 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -453,7 +453,7 @@ static unsigned print_name(const char *name)
name = printable_string2(&uni_stat, name);
if (!(option_mask32 & OPT_Q)) {
- fputs(name, stdout);
+ fputs_stdout(name);
return uni_stat.unicode_width;
}
diff --git a/coreutils/mknod.c b/coreutils/mknod.c
index eee0ac71d..b10fe4fc3 100644
--- a/coreutils/mknod.c
+++ b/coreutils/mknod.c
@@ -36,7 +36,9 @@
//usage: "$ mknod /dev/fd0 b 2 0\n"
//usage: "$ mknod -m 644 /tmp/pipe p\n"
-#include <sys/sysmacros.h> // For makedev
+#ifdef __linux__
+# include <sys/sysmacros.h> // For makedev
+#endif
#include "libbb.h"
#include "libcoreutils/coreutils.h"
diff --git a/coreutils/nl.c b/coreutils/nl.c
index 800b73c26..d06673881 100644
--- a/coreutils/nl.c
+++ b/coreutils/nl.c
@@ -68,7 +68,7 @@ int nl_main(int argc UNUSED_PARAM, char **argv)
&ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b);
ns.all = (opt_b[0] == 'a');
ns.nonempty = (opt_b[0] == 't');
- ns.empty_str = xasprintf("%*s\n", ns.width + (int)strlen(ns.sep), "");
+ ns.empty_str = xasprintf("%*s", ns.width + (int)strlen(ns.sep), "");
argv += optind;
if (!*argv)
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index d5bd7bfe8..5b5e56a21 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -422,19 +422,19 @@ print_named_ascii(size_t n_bytes, const char *block,
masked_c &= 0x7f;
if (masked_c == 0x7f) {
- fputs(" del", stdout);
+ fputs_stdout(" del");
continue;
}
if (masked_c > ' ') {
buf[3] = masked_c;
- fputs(buf, stdout);
+ fputs_stdout(buf);
continue;
}
/* Why? Because printf(" %3.3s") is much slower... */
buf[6] = charname[masked_c][0];
buf[7] = charname[masked_c][1];
buf[8] = charname[masked_c][2];
- fputs(buf+5, stdout);
+ fputs_stdout(buf+5);
}
}
@@ -451,7 +451,7 @@ print_ascii(size_t n_bytes, const char *block,
if (ISPRINT(c)) {
buf[3] = c;
- fputs(buf, stdout);
+ fputs_stdout(buf);
continue;
}
switch (c) {
@@ -485,7 +485,7 @@ print_ascii(size_t n_bytes, const char *block,
buf[8] = (c & 7) + '0';
s = buf + 5;
}
- fputs(s, stdout);
+ fputs_stdout(s);
}
}
@@ -881,7 +881,7 @@ format_address_label(off_t address, char c)
static void
dump_hexl_mode_trailer(size_t n_bytes, const char *block)
{
- fputs(" >", stdout);
+ fputs_stdout(" >");
while (n_bytes--) {
unsigned c = *(unsigned char *) block++;
c = (ISPRINT(c) ? c : '.');
@@ -1121,13 +1121,13 @@ dump_strings(off_t address, off_t end_offset)
for (i = 0; (c = buf[i]); i++) {
switch (c) {
- case '\007': fputs("\\a", stdout); break;
- case '\b': fputs("\\b", stdout); break;
- case '\f': fputs("\\f", stdout); break;
- case '\n': fputs("\\n", stdout); break;
- case '\r': fputs("\\r", stdout); break;
- case '\t': fputs("\\t", stdout); break;
- case '\v': fputs("\\v", stdout); break;
+ case '\007': fputs_stdout("\\a"); break;
+ case '\b': fputs_stdout("\\b"); break;
+ case '\f': fputs_stdout("\\f"); break;
+ case '\n': fputs_stdout("\\n"); break;
+ case '\r': fputs_stdout("\\r"); break;
+ case '\t': fputs_stdout("\\t"); break;
+ case '\v': fputs_stdout("\\v"); break;
default: putchar(c);
}
}
diff --git a/coreutils/paste.c b/coreutils/paste.c
index fd2aa5027..7def4de11 100644
--- a/coreutils/paste.c
+++ b/coreutils/paste.c
@@ -53,7 +53,7 @@ static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt)
--active_files;
continue;
}
- fputs(line, stdout);
+ fputs_stdout(line);
free(line);
delim = '\n';
if (i != file_cnt - 1) {
@@ -79,7 +79,7 @@ static void paste_files_separate(FILE** files, char* delims, int del_cnt)
line = NULL;
while ((next_line = xmalloc_fgetline(files[i])) != NULL) {
if (line) {
- fputs(line, stdout);
+ fputs_stdout(line);
free(line);
delim = delims[del_idx++];
if (del_idx == del_cnt)
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 073b2c67b..a8393468e 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -439,7 +439,7 @@ static void print_it(const char *masterformat,
/* print preceding string */
*p = '\0';
- fputs(b, stdout);
+ fputs_stdout(b);
p += len;
b = p + 1;
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 19253964c..ba2b78317 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -855,7 +855,7 @@ static void wrapf(const char *message, ...)
}
}
}
- fputs(buf, stdout);
+ fputs_stdout(buf);
G.current_col += buflen;
if (buf[buflen-1] == '\n')
G.current_col = 0;
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 164b208ea..02b037276 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -319,7 +319,7 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv)
}
if (col == 0) {
- fputs(dst_buf, stdout);
+ fputs_stdout(dst_buf);
} else {
char *result = dst_buf;
if (rem == 0)
diff --git a/coreutils/yes.c b/coreutils/yes.c
index 9a435a761..0ad25926f 100644
--- a/coreutils/yes.c
+++ b/coreutils/yes.c
@@ -43,7 +43,7 @@ int yes_main(int argc UNUSED_PARAM, char **argv)
do {
pp = argv;
while (1) {
- fputs(*pp, stdout);
+ fputs_stdout(*pp);
if (!*++pp)
break;
putchar(' ');
diff --git a/editors/awk.c b/editors/awk.c
index 2c15f9e4e..b4f6a3741 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2155,7 +2155,10 @@ static int fmt_num(char *b, int size, const char *format, double n, int int_as_i
}
/* formatted output into an allocated buffer, return ptr to buffer */
-static char *awk_printf(node *n)
+#if !ENABLE_FEATURE_AWK_GNU_EXTENSIONS
+# define awk_printf(a, b) awk_printf(a)
+#endif
+static char *awk_printf(node *n, int *len)
{
char *b = NULL;
char *fmt, *s, *f;
@@ -2209,6 +2212,10 @@ static char *awk_printf(node *n)
nvfree(v);
b = xrealloc(b, i + 1);
b[i] = '\0';
+#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
+ if (len)
+ *len = i;
+#endif
return b;
}
@@ -2666,6 +2673,7 @@ static var *evaluate(node *op, var *res)
case XC( OC_PRINT ):
case XC( OC_PRINTF ): {
FILE *F = stdout;
+ IF_FEATURE_AWK_GNU_EXTENSIONS(int len;)
if (op->r.n) {
rstream *rsm = newfile(R.s);
@@ -2703,8 +2711,12 @@ static var *evaluate(node *op, var *res)
fputs(getvar_s(intvar[ORS]), F);
} else { /* OC_PRINTF */
- char *s = awk_printf(op1);
+ char *s = awk_printf(op1, &len);
+#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
+ fwrite(s, len, 1, F);
+#else
fputs(s, F);
+#endif
free(s);
}
fflush(F);
@@ -2978,7 +2990,7 @@ static var *evaluate(node *op, var *res)
break;
case XC( OC_SPRINTF ):
- setvar_p(res, awk_printf(op1));
+ setvar_p(res, awk_printf(op1, NULL));
break;
case XC( OC_UNARY ): {
diff --git a/editors/ed.c b/editors/ed.c
index d3ae8da92..c50faeefa 100644
--- a/editors/ed.c
+++ b/editors/ed.c
@@ -553,7 +553,7 @@ static int printLines(int num1, int num2, int expandFlag)
fputc_printable(ch | PRINTABLE_META, stdout);
}
- fputs("$\n", stdout);
+ fputs_stdout("$\n");
setCurNum(num1++);
lp = lp->next;
diff --git a/editors/vi.c b/editors/vi.c
index 01597fa5e..458ca6293 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -522,7 +522,7 @@ static void show_help(void)
static void write1(const char *out)
{
- fputs(out, stdout);
+ fputs_stdout(out);
}
#if ENABLE_FEATURE_VI_WIN_RESIZE
@@ -3047,12 +3047,15 @@ static int find_range(char **start, char **stop, char c)
do_cmd(c); // execute movement cmd
dot_end(); // find NL
q = dot;
- } else {
- // nothing -- this causes any other values of c to
- // represent the one-character range under the
- // cursor. this is correct for ' ' and 'l', but
- // perhaps no others.
- //
+ } else /* if (c == ' ' || c == 'l') */ {
+ // forward motion by character
+ int tmpcnt = (cmdcnt ?: 1);
+ do_cmd(c); // execute movement cmd
+ // exclude last char unless range isn't what we expected
+ // this indicates we've hit EOL
+ if (tmpcnt == dot - p)
+ dot--;
+ q = dot;
}
if (q < p) {
t = q;
diff --git a/include/libbb.h b/include/libbb.h
index cae54658b..135d9111d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -106,7 +106,11 @@
# define updwtmpx updwtmp
# define _PATH_UTMPX _PATH_UTMP
# else
-# include <utmp.h>
+# if !defined(__FreeBSD__)
+# include <utmp.h>
+# else
+# define _PATH_UTMPX "/var/run/utx.active"
+# endif
# include <utmpx.h>
# if defined _PATH_UTMP && !defined _PATH_UTMPX
# define _PATH_UTMPX _PATH_UTMP
@@ -657,6 +661,7 @@ void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
+void xgettimeofday(struct timeval *tv) FAST_FUNC;
void xsettimeofday(const struct timeval *tv) FAST_FUNC;
@@ -869,6 +874,7 @@ char *xmalloc_substitute_string(const char *src, int count, const char *sub, con
int bb_putchar(int ch) FAST_FUNC;
/* Note: does not use stdio, writes to fd 2 directly */
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 *auto_string(char *str) FAST_FUNC;
// gcc-4.1.1 still isn't good enough at optimizing it
diff --git a/include/platform.h b/include/platform.h
index 085387fd8..d991f3140 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -319,7 +319,7 @@ typedef unsigned smalluint;
#endif
/* Define bb_setpgrp */
-#if defined(__digital__) && defined(__unix__)
+#if (defined(__digital__) && defined(__unix__)) || defined(__FreeBSD__)
/* use legacy setpgrp(pid_t, pid_t) for now. move to platform.c */
# define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me, __me); } while (0)
#else
diff --git a/init/bootchartd.c b/init/bootchartd.c
index 750f67356..ae1ee9d9a 100644
--- a/init/bootchartd.c
+++ b/init/bootchartd.c
@@ -218,10 +218,10 @@ static char *make_tempdir(void)
static void do_logging(unsigned sample_period_us, int process_accounting)
{
- FILE *proc_stat = xfopen("proc_stat.log", "w");
- FILE *proc_diskstats = xfopen("proc_diskstats.log", "w");
- //FILE *proc_netdev = xfopen("proc_netdev.log", "w");
- FILE *proc_ps = xfopen("proc_ps.log", "w");
+ FILE *proc_stat = xfopen_for_write("proc_stat.log");
+ FILE *proc_diskstats = xfopen_for_write("proc_diskstats.log");
+ //FILE *proc_netdev = xfopen_for_write("proc_netdev.log");
+ FILE *proc_ps = xfopen_for_write("proc_ps.log");
int look_for_login_process = (getppid() == 1);
unsigned count = 60*1000*1000 / sample_period_us; /* ~1 minute */
@@ -268,7 +268,7 @@ static void finalize(char *tempdir, const char *prog, int process_accounting)
//local pacct=
//[ -e kernel_pacct ] && pacct=kernel_pacct
- FILE *header_fp = xfopen("header", "w");
+ FILE *header_fp = xfopen_for_write("header");
if (process_accounting)
acct(NULL);
diff --git a/klibc-utils/nuke.c b/klibc-utils/nuke.c
index d7c16f5cf..8c20c5e11 100644
--- a/klibc-utils/nuke.c
+++ b/klibc-utils/nuke.c
@@ -5,7 +5,7 @@
*/
//config:config NUKE
//config: bool "nuke (2.9 kb)"
-//config: default y
+//config: default n # off by default: too "accidentally destructive"
//config: help
//config: Alias to "rm -rf".
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 5f59f1273..542211255 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -176,7 +176,7 @@ void FAST_FUNC bb_show_usage(void)
int FAST_FUNC find_applet_by_name(const char *name)
{
- unsigned i, max;
+ unsigned i;
int j;
const char *p;
@@ -200,105 +200,43 @@ int FAST_FUNC find_applet_by_name(const char *name)
#endif
p = applet_names;
- i = 0;
#if KNOWN_APPNAME_OFFSETS <= 0
- max = NUM_APPLETS;
+ i = 0;
#else
- max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS;
+ i = NUM_APPLETS * (KNOWN_APPNAME_OFFSETS - 1);
for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) {
const char *pp = applet_names + applet_nameofs[j];
if (strcmp(name, pp) >= 0) {
//bb_error_msg("name:'%s' >= pp:'%s'", name, pp);
p = pp;
- i = max - NUM_APPLETS;
break;
}
- max -= NUM_APPLETS;
+ i -= NUM_APPLETS;
}
- max /= (unsigned)KNOWN_APPNAME_OFFSETS;
i /= (unsigned)KNOWN_APPNAME_OFFSETS;
- //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max);
+ //bb_error_msg("name:'%s' starting from:'%s' i:%u", name, p, i);
#endif
/* Open-coded linear search without strcmp/strlen calls for speed */
-
-#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/
- /* skip "[\0" name, it's surely not it */
- if (ENABLE_TEST && LONE_CHAR(p, '['))
- i++, p += 2;
- /* All remaining applet names in p[] are at least 2 chars long */
- /* name[] is also at least 2 chars long */
-
- n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16);
- while (i < max) {
- uint32_t p32;
- char ch;
-
- /* Quickly check match of the first 3 bytes */
- move_from_unaligned32(p32, p);
- p += 3;
- if ((p32 & 0x00ffffff) != n32) {
- /* Most likely case: 3 first bytes do not match */
- i++;
- if ((p32 & 0x00ff0000) == '\0')
- continue; // p[2] was NUL
- p++;
- if ((p32 & 0xff000000) == '\0')
- continue; // p[3] was NUL
- /* p[0..3] aren't matching and none is NUL, check the rest */
- while (*p++ != '\0')
- continue;
- continue;
- }
-
- /* Unlikely branch: first 3 bytes ([0..2]) match */
- if ((p32 & 0x00ff0000) == '\0') {
- /* name is 2-byte long, it is full match */
- //bb_error_msg("found:'%s' i:%u", name, i);
- return i;
- }
- /* Check remaining bytes [3..NUL] */
- ch = (p32 >> 24);
- j = 3;
- while (ch == name[j]) {
- if (ch == '\0') {
- //bb_error_msg("found:'%s' i:%u", name, i);
- return i;
- }
- ch = *++p;
- j++;
- }
- /* Not a match. Skip it, including NUL */
- while (ch != '\0')
- ch = *++p;
- p++;
- i++;
- }
- return -1;
-#else
- while (i < max) {
- char ch;
- j = 0;
- /* Do we see "name\0" in applet_names[p] position? */
- while ((ch = *p) == name[j]) {
- if (ch == '\0') {
+ while (*p) {
+ /* Do we see "name\0" at current position in applet_names? */
+ for (j = 0; *p == name[j]; ++j) {
+ if (*p++ == '\0') {
//bb_error_msg("found:'%s' i:%u", name, i);
return i; /* yes */
}
- p++;
- j++;
}
- /* No.
- * p => 1st non-matching char in applet_names[],
- * skip to and including NUL.
- */
- while (ch != '\0')
- ch = *++p;
- p++;
+ /* No. Have we gone too far, alphabetically? */
+ if (*p > name[j]) {
+ //bb_error_msg("break:'%s' i:%u", name, i);
+ break;
+ }
+ /* No. Move to the start of the next applet name. */
+ while (*p++ != '\0')
+ continue;
i++;
}
return -1;
-#endif
}
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
index 2dcead35a..66d6a479e 100644
--- a/libbb/bb_askpass.c
+++ b/libbb/bb_askpass.c
@@ -25,7 +25,7 @@ char* FAST_FUNC bb_ask_noecho(int fd, int timeout, const char *prompt)
/* Was buggy: was printing prompt *before* flushing input,
* which was upsetting "expect" based scripts of some users.
*/
- fputs(prompt, stdout);
+ fputs_stdout(prompt);
fflush_all();
tcgetattr(fd, &oldtio);
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index a06e57d3d..d8cd033a3 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -63,13 +63,19 @@ int FAST_FUNC index_in_str_array(const char *const string_array[], const char *k
int FAST_FUNC index_in_strings(const char *strings, const char *key)
{
- int idx = 0;
+ int j, idx = 0;
while (*strings) {
- if (strcmp(strings, key) == 0) {
- return idx;
+ /* Do we see "key\0" at current position in strings? */
+ for (j = 0; *strings == key[j]; ++j) {
+ if (*strings++ == '\0') {
+ //bb_error_msg("found:'%s' i:%u", key, idx);
+ return idx; /* yes */
+ }
}
- strings += strlen(strings) + 1; /* skip NUL */
+ /* No. Move to the start of the next string. */
+ while (*strings++ != '\0')
+ continue;
idx++;
}
return -1;
diff --git a/libbb/dump.c b/libbb/dump.c
index 1ba1132b3..fb7849e7d 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -560,7 +560,7 @@ static void display(priv_dumper_t* dumper)
) {
if (dumper->pub.eofstring) {
/* xxd support: requested to not pad incomplete blocks */
- fputs(dumper->pub.eofstring, stdout);
+ fputs_stdout(dumper->pub.eofstring);
return;
}
if (!(pr->flags & (F_TEXT | F_BPAD)))
diff --git a/libbb/fgets_str.c b/libbb/fgets_str.c
index 1a7f2e9e0..c884ef8af 100644
--- a/libbb/fgets_str.c
+++ b/libbb/fgets_str.c
@@ -17,7 +17,7 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
int linebufsz = 0;
int idx = 0;
int ch;
- size_t maxsz = *maxsz_p;
+ size_t maxsz = maxsz_p ? *maxsz_p : INT_MAX - 4095;
while (1) {
ch = fgetc(file);
@@ -53,7 +53,8 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
/* Grow/shrink *first*, then store NUL */
linebuf = xrealloc(linebuf, idx + 1);
linebuf[idx] = '\0';
- *maxsz_p = idx;
+ if (maxsz_p)
+ *maxsz_p = idx;
return linebuf;
}
@@ -63,23 +64,15 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
* Return NULL if EOF is reached immediately. */
char* FAST_FUNC xmalloc_fgets_str(FILE *file, const char *terminating_string)
{
- size_t maxsz = INT_MAX - 4095;
- return xmalloc_fgets_internal(file, terminating_string, 0, &maxsz);
+ return xmalloc_fgets_internal(file, terminating_string, 0, NULL);
}
char* FAST_FUNC xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p)
{
- size_t maxsz;
-
- if (!maxsz_p) {
- maxsz = INT_MAX - 4095;
- maxsz_p = &maxsz;
- }
return xmalloc_fgets_internal(file, terminating_string, 0, maxsz_p);
}
char* FAST_FUNC xmalloc_fgetline_str(FILE *file, const char *terminating_string)
{
- size_t maxsz = INT_MAX - 4095;
- return xmalloc_fgets_internal(file, terminating_string, 1, &maxsz);
+ return xmalloc_fgets_internal(file, terminating_string, 1, NULL);
}
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 75de88e77..367396b91 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -312,7 +312,7 @@ static void BB_PUTCHAR(wchar_t c)
ssize_t len = wcrtomb(buf, c, &mbst);
if (len > 0) {
buf[len] = '\0';
- fputs(buf, stdout);
+ fputs_stdout(buf);
}
} else {
/* In this case, c is always one byte */
@@ -460,7 +460,7 @@ static void beep(void)
*/
static void put_prompt_custom(bool is_full)
{
- fputs((is_full ? cmdedit_prompt : prompt_last_line), stdout);
+ fputs_stdout((is_full ? cmdedit_prompt : prompt_last_line));
cursor = 0;
cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */
cmdedit_x = cmdedit_prmt_len % cmdedit_termw;
@@ -1851,7 +1851,7 @@ static void ask_terminal(void)
pfd.events = POLLIN;
if (safe_poll(&pfd, 1, 0) == 0) {
S.sent_ESC_br6n = 1;
- fputs(ESC"[6n", stdout);
+ fputs_stdout(ESC"[6n");
fflush_all(); /* make terminal see it ASAP! */
}
}
@@ -2957,7 +2957,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
#undef read_line_input
int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
{
- fputs(prompt, stdout);
+ fputs_stdout(prompt);
fflush_all();
if (!fgets(command, maxsize, stdin))
return -1;
diff --git a/libbb/login.c b/libbb/login.c
index 7f593d80d..af860c277 100644
--- a/libbb/login.c
+++ b/libbb/login.c
@@ -120,7 +120,7 @@ void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
buf[0] = c;
}
}
- fputs(outbuf, stdout);
+ fputs_stdout(outbuf);
}
fclose(fp);
fflush_all();
@@ -130,8 +130,8 @@ void FAST_FUNC print_login_prompt(void)
{
char *hostname = safe_gethostname();
- fputs(hostname, stdout);
- fputs(LOGIN, stdout);
+ fputs_stdout(hostname);
+ fputs_stdout(LOGIN);
fflush_all();
free(hostname);
}
diff --git a/libbb/print_numbered_lines.c b/libbb/print_numbered_lines.c
index d6459d7c3..b64f85597 100644
--- a/libbb/print_numbered_lines.c
+++ b/libbb/print_numbered_lines.c
@@ -22,10 +22,11 @@ int FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename
if (ns->all
|| (ns->nonempty && line[0])
) {
- printf("%*u%s%s\n", ns->width, N, ns->sep, line);
+ printf("%*u%s", ns->width, N, ns->sep);
N += ns->inc;
} else if (ns->empty_str)
- fputs(ns->empty_str, stdout);
+ fputs_stdout(ns->empty_str);
+ puts(line);
free(line);
}
ns->start = N;
diff --git a/libbb/procps.c b/libbb/procps.c
index 75969947b..f56b71b21 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -21,40 +21,29 @@ typedef struct cache_t {
int size;
} cache_t;
-static cache_t username, groupname;
+static cache_t *cache_user_group;
-static void clear_cache(cache_t *cp)
-{
- free(cp->cache);
- cp->cache = NULL;
- cp->size = 0;
-}
void FAST_FUNC clear_username_cache(void)
{
- clear_cache(&username);
- clear_cache(&groupname);
-}
-
-#if 0 /* more generic, but we don't need that yet */
-/* Returns -N-1 if not found. */
-/* cp->cache[N] is allocated and must be filled in this case */
-static int get_cached(cache_t *cp, uid_t id)
-{
- int i;
- for (i = 0; i < cp->size; i++)
- if (cp->cache[i].id == id)
- return i;
- i = cp->size++;
- cp->cache = xrealloc_vector(cp->cache, 2, i);
- cp->cache[i++].id = id;
- return -i;
+ if (cache_user_group) {
+ free(cache_user_group[0].cache);
+ free(cache_user_group[1].cache);
+ free(cache_user_group);
+ cache_user_group = NULL;
+ }
}
-#endif
-static char* get_cached(cache_t *cp, uid_t id,
+static char* get_cached(int user_group, uid_t id,
char* FAST_FUNC x2x_utoa(uid_t id))
{
+ cache_t *cp;
int i;
+
+ if (!cache_user_group)
+ cache_user_group = xzalloc(sizeof(cache_user_group[0]) * 2);
+
+ cp = &cache_user_group[user_group];
+
for (i = 0; i < cp->size; i++)
if (cp->cache[i].id == id)
return cp->cache[i].name;
@@ -67,11 +56,11 @@ static char* get_cached(cache_t *cp, uid_t id,
}
const char* FAST_FUNC get_cached_username(uid_t uid)
{
- return get_cached(&username, uid, uid2uname_utoa);
+ return get_cached(0, uid, uid2uname_utoa);
}
const char* FAST_FUNC get_cached_groupname(gid_t gid)
{
- return get_cached(&groupname, gid, gid2group_utoa);
+ return get_cached(1, gid, gid2group_utoa);
}
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index a60c33c35..3463fd95b 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -7,7 +7,9 @@
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
#if !ENABLE_USE_BB_CRYPT
-#include <crypt.h>
+# if !defined(__FreeBSD__)
+# include <crypt.h>
+# endif
#endif
#include "libbb.h"
diff --git a/libbb/time.c b/libbb/time.c
index 74a69eefb..cf5f2e5c8 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -291,19 +291,19 @@ unsigned FAST_FUNC monotonic_sec(void)
unsigned long long FAST_FUNC monotonic_ns(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
}
unsigned long long FAST_FUNC monotonic_us(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
}
unsigned long long FAST_FUNC monotonic_ms(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
}
unsigned FAST_FUNC monotonic_sec(void)
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index 7b67f30cd..a228075cc 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -48,7 +48,7 @@ static void check_selinux_update_passwd(const char *username)
bb_simple_error_msg_and_die("SELinux: access denied");
}
if (ENABLE_FEATURE_CLEAN_UP)
- freecon(context);
+ freecon(seuser);
}
#else
# define check_selinux_update_passwd(username) ((void)0)
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index aea995a5c..f0399ca45 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -318,6 +318,11 @@ int FAST_FUNC bb_putchar(int ch)
return putchar(ch);
}
+int FAST_FUNC fputs_stdout(const char *s)
+{
+ return fputs(s, stdout);
+}
+
/* Die with an error message if we can't copy an entire FILE* to stdout,
* then close that file. */
void FAST_FUNC xprint_and_close_file(FILE *file)
@@ -720,3 +725,14 @@ void FAST_FUNC xsettimeofday(const struct timeval *tv)
if (settimeofday(tv, NULL))
bb_simple_perror_msg_and_die("settimeofday");
}
+
+void FAST_FUNC xgettimeofday(struct timeval *tv)
+{
+#if 0
+ if (gettimeofday(tv, NULL))
+ bb_simple_perror_msg_and_die("gettimeofday");
+#else
+ /* Never fails on Linux */
+ gettimeofday(tv, NULL);
+#endif
+}
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c
index 645f1bb09..2109e2eb5 100644
--- a/loginutils/cryptpw.c
+++ b/loginutils/cryptpw.c
@@ -32,7 +32,7 @@
//kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o
//usage:#define cryptpw_trivial_usage
-//usage: "[-s] [-p N] [-m TYPE] [-S SALT] [PASSWORD] [SALT]"
+//usage: "[-P FD] [-m TYPE] [-S SALT] [PASSWORD] [SALT]"
/* We do support -s, we just don't mention it */
//usage:#define cryptpw_full_usage "\n\n"
//usage: "Print crypt(3) hashed PASSWORD\n"
@@ -72,8 +72,8 @@ ENVIRONMENT
A list of options which will be evaluated before the ones
specified on the command line.
BUGS
- This programs suffers of a bad case of featuritis.
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ This program suffers of a bad case of featuritis.
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Very true...
diff --git a/mailutils/mail.c b/mailutils/mail.c
index 61e5053bc..f48b41bab 100644
--- a/mailutils/mail.c
+++ b/mailutils/mail.c
@@ -6,7 +6,13 @@
*
* Licensed under GPLv2, see file LICENSE in this source tree.
*/
-#include <sys/prctl.h>
+#if defined(__linux__)
+# include <sys/prctl.h>
+# define PRCTL
+#elif defined(__FreeBSD__)
+# include <sys/procctl.h>
+# define PROCCTL
+#endif
#include "libbb.h"
#include "mail.h"
@@ -55,7 +61,14 @@ void FAST_FUNC launch_helper(const char **argv)
xmove_fd(child_in.rd, STDIN_FILENO);
xmove_fd(child_out.wr, STDOUT_FILENO);
// if parent dies, get SIGTERM
+#if defined(PRCTL)
prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
+#elif defined(PROCCTL)
+ {
+ int signum = SIGTERM;
+ procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum);
+ }
+#endif
// try to execute connection helper
// NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec
BB_EXECVP_or_die((char**)argv);
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 59e18a8c1..02a61ac49 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -231,7 +231,7 @@ typedef struct BcNum {
#define BC_NUM_MAX_IBASE 36
// larger value might speed up BIGNUM calculations a bit:
#define BC_NUM_DEF_SIZE 16
-#define BC_NUM_PRINT_WIDTH 69
+#define BC_NUM_PRINT_WIDTH 70
#define BC_NUM_KARATSUBA_LEN 32
@@ -1827,7 +1827,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
#define zbc_num_k(...) (zbc_num_k(__VA_ARGS__) COMMA_SUCCESS)
{
BcStatus s;
- size_t max = BC_MAX(a->len, b->len), max2 = (max + 1) / 2;
+ size_t max, max2;
BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
bool aone;
@@ -1841,9 +1841,9 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
RETURN_STATUS(BC_STATUS_SUCCESS);
}
- if (a->len + b->len < BC_NUM_KARATSUBA_LEN
- || a->len < BC_NUM_KARATSUBA_LEN
+ if (a->len < BC_NUM_KARATSUBA_LEN
|| b->len < BC_NUM_KARATSUBA_LEN
+ /* || a->len + b->len < BC_NUM_KARATSUBA_LEN - redundant check */
) {
size_t i, j, len;
@@ -1877,6 +1877,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
RETURN_STATUS(BC_STATUS_SUCCESS);
}
+ max = BC_MAX(a->len, b->len);
bc_num_init(&l1, max);
bc_num_init(&h1, max);
bc_num_init(&l2, max);
@@ -1888,6 +1889,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
bc_num_init(&z2, max);
bc_num_init(&temp, max + max);
+ max2 = (max + 1) / 2;
bc_num_split(a, max2, &l1, &h1);
bc_num_split(b, max2, &l2, &h2);
@@ -2524,9 +2526,6 @@ static void xc_read_line(BcVec *vec, FILE *fp)
#if ENABLE_FEATURE_BC_INTERACTIVE
if (G_interrupt) { // ^C was pressed
-# if ENABLE_FEATURE_EDITING
- intr:
-# endif
if (fp != stdin) {
// ^C while running a script (bc SCRIPT): die.
// We do not return to interactive prompt:
@@ -2537,11 +2536,11 @@ static void xc_read_line(BcVec *vec, FILE *fp)
// the shell would be unexpected.
xfunc_die();
}
- // ^C while interactive input
+ // There was ^C while running calculations
G_interrupt = 0;
- // GNU bc says "interrupted execution."
+ // GNU bc says "interrupted execution." (to stdout, not stderr)
// GNU dc says "Interrupt!"
- fputs("\ninterrupted execution\n", stderr);
+ puts("\ninterrupted execution");
}
# if ENABLE_FEATURE_EDITING
@@ -2552,9 +2551,10 @@ static void xc_read_line(BcVec *vec, FILE *fp)
# define line_buf bb_common_bufsiz1
n = read_line_input(G.line_input_state, "", line_buf, COMMON_BUFSIZE);
if (n <= 0) { // read errors or EOF, or ^D, or ^C
- if (n == 0) // ^C
- goto intr;
- bc_vec_pushZeroByte(vec); // ^D or EOF (or error)
+ //GNU bc prints this on ^C:
+ //if (n == 0) // ^C
+ // puts("(interrupt) Exiting bc.");
+ bc_vec_pushZeroByte(vec);
return;
}
i = 0;
@@ -6448,7 +6448,7 @@ static BC_STATUS zdc_program_printStream(void)
char *str;
idx = (r->t == XC_RESULT_STR) ? r->d.id.idx : n->rdx;
str = *xc_program_str(idx);
- fputs(str, stdout);
+ fputs_stdout(str);
}
RETURN_STATUS(s);
@@ -7372,11 +7372,29 @@ static unsigned xc_vm_envLen(const char *var)
lenv = getenv(var);
len = BC_NUM_PRINT_WIDTH;
- if (!lenv) return len;
+ if (lenv) {
+ len = bb_strtou(lenv, NULL, 10);
+ if (len == 0 || len > INT_MAX)
+ len = INT_MAX;
+ if (errno)
+ len = BC_NUM_PRINT_WIDTH;
+ }
- len = bb_strtou(lenv, NULL, 10) - 1;
- if (errno || len < 2 || len >= INT_MAX)
- len = BC_NUM_PRINT_WIDTH;
+ // dc (GNU bc 1.07.1) 1.4.1 seems to use width
+ // 1 char wider than bc from the same package.
+ // Both default width, and xC_LINE_LENGTH=N are wider:
+ // "DC_LINE_LENGTH=5 dc -e'123456 p'" prints:
+ // |1234\ |
+ // |56 |
+ // "echo '123456' | BC_LINE_LENGTH=5 bc" prints:
+ // |123\ |
+ // |456 |
+ // Do the same, but it might be a bug in GNU package
+ if (IS_BC)
+ len--;
+
+ if (len < 2)
+ len = IS_BC ? BC_NUM_PRINT_WIDTH - 1 : BC_NUM_PRINT_WIDTH;
return len;
}
@@ -7467,16 +7485,6 @@ int dc_main(int argc UNUSED_PARAM, char **argv)
INIT_G();
- // TODO: dc (GNU bc 1.07.1) 1.4.1 seems to use width
- // 1 char wider than bc from the same package.
- // Both default width, and xC_LINE_LENGTH=N are wider:
- // "DC_LINE_LENGTH=5 dc -e'123456 p'" prints:
- // |1234\ |
- // |56 |
- // "echo '123456' | BC_LINE_LENGTH=5 bc" prints:
- // |123\ |
- // |456 |
- // Do the same, or it's a bug?
xc_vm_init("DC_LINE_LENGTH");
// Run -e'SCRIPT' and -fFILE in order of appearance, then handle FILEs
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index fac11d339..21a498d0f 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -107,8 +107,8 @@ enum {
static void putcsi(const char *s)
{
- fputs(ESC"[", stdout);
- fputs(s, stdout);
+ fputs_stdout(ESC"[");
+ fputs_stdout(s);
}
static void clrscr(void)
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index cda17ee00..48135921d 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -1149,12 +1149,12 @@ static void NORETURN list_i2c_busses_and_exit(void)
/* Simple version for ISA chips. */
snprintf(path, NAME_MAX, "%s/%s/name",
i2cdev_path, de->d_name);
- fp = fopen(path, "r");
+ fp = fopen_for_read(path);
if (fp == NULL) {
snprintf(path, NAME_MAX,
"%s/%s/device/name",
i2cdev_path, de->d_name);
- fp = fopen(path, "r");
+ fp = fopen_for_read(path);
}
/* Non-ISA chips require the hard-way. */
@@ -1175,7 +1175,7 @@ static void NORETURN list_i2c_busses_and_exit(void)
"%s/%s/device/%s/name",
i2cdev_path, de->d_name,
subde->d_name);
- fp = fopen(path, "r");
+ fp = fopen_for_read(path);
break;
}
}
diff --git a/miscutils/strings.c b/miscutils/strings.c
index 51412f401..e4a68227e 100644
--- a/miscutils/strings.c
+++ b/miscutils/strings.c
@@ -92,7 +92,7 @@ int strings_main(int argc UNUSED_PARAM, char **argv)
if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) {
printf(radix_fmt, offset - n);
}
- fputs(string, stdout);
+ fputs_stdout(string);
}
count++;
}
diff --git a/miscutils/ts.c b/miscutils/ts.c
index f2d367654..6e5d77bda 100644
--- a/miscutils/ts.c
+++ b/miscutils/ts.c
@@ -47,13 +47,13 @@ int ts_main(int argc UNUSED_PARAM, char **argv)
#define date_buf bb_common_bufsiz1
setup_common_bufsiz();
- gettimeofday(&base, NULL);
+ xgettimeofday(&base);
while ((line = xmalloc_fgets(stdin)) != NULL) {
struct timeval ts;
struct tm tm_time;
- gettimeofday(&ts, NULL);
+ xgettimeofday(&ts);
if (opt) {
/* -i and/or -s */
struct timeval ts1 = ts1;
diff --git a/networking/brctl.c b/networking/brctl.c
index f057f9b60..e1f3e6445 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -156,7 +156,7 @@ static int show_bridge(const char *name, int need_hdr)
else
if (LONE_CHAR(filedata, '1'))
strcpy(filedata, "yes");
- fputs(filedata, stdout);
+ fputs_stdout(filedata);
/* sfx points past "BR/bridge/", turn it into "BR/brif": */
sfx[-4] = 'f'; sfx[-3] = '\0';
diff --git a/networking/httpd.c b/networking/httpd.c
index 4346141ee..e6757d943 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -298,6 +298,11 @@
# include <sys/sendfile.h>
#endif
+/* see sys/netinet6/in6.h */
+#if defined(__FreeBSD__)
+# define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
#define DEBUG 0
#define IOBUF_SIZE 8192
@@ -1871,7 +1876,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
send_headers(HTTP_OK);
#if ENABLE_FEATURE_USE_SENDFILE
{
- off_t offset = range_start;
+ off_t offset = (range_start < 0) ? 0 : range_start;
while (1) {
/* sz is rounded down to 64k */
ssize_t sz = MAXINT(ssize_t) - 0xffff;
@@ -2486,8 +2491,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
if (STRNCASECMP(iobuf, "Range:") == 0) {
/* We know only bytes=NNN-[MMM] */
char *s = skip_whitespace(iobuf + sizeof("Range:")-1);
- if (is_prefixed_with(s, "bytes=")) {
- s += sizeof("bytes=")-1;
+ s = is_prefixed_with(s, "bytes=");
+ if (s) {
range_start = BB_STRTOOFF(s, &s, 10);
if (s[0] != '-' || range_start < 0) {
range_start = -1;
@@ -2783,12 +2788,12 @@ int httpd_main(int argc UNUSED_PARAM, char **argv)
, &verbose
);
if (opt & OPT_DECODE_URL) {
- fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout);
+ fputs_stdout(percent_decode_in_place(url_for_decode, /*strict:*/ 0));
return 0;
}
#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
if (opt & OPT_ENCODE_URL) {
- fputs(encodeString(url_for_encode), stdout);
+ fputs_stdout(encodeString(url_for_encode));
return 0;
}
#endif
diff --git a/networking/inetd.c b/networking/inetd.c
index 9f5a436d6..febfb7b73 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -1701,7 +1701,7 @@ static uint32_t machtime(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return htonl((uint32_t)(tv.tv_sec + 2208988800U));
}
/* ARGSUSED */
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index dfd84c000..17a838411 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -192,20 +192,20 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
printf("%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));
if (tb[IFLA_ADDRESS]) {
- fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
+ fputs_stdout(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
RTA_PAYLOAD(tb[IFLA_ADDRESS]),
ifi->ifi_type,
- b1, sizeof(b1)), stdout);
+ b1, sizeof(b1)));
}
if (tb[IFLA_BROADCAST]) {
if (ifi->ifi_flags & IFF_POINTOPOINT)
printf(" peer ");
else
printf(" brd ");
- fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
+ fputs_stdout(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
RTA_PAYLOAD(tb[IFLA_BROADCAST]),
ifi->ifi_type,
- b1, sizeof(b1)), stdout);
+ b1, sizeof(b1)));
}
}
bb_putchar('\n');
@@ -307,9 +307,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
printf(" family %d ", ifa->ifa_family);
if (rta_tb[IFA_LOCAL]) {
- fputs(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])),
- stdout
- );
+ fputs_stdout(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])));
if (rta_tb[IFA_ADDRESS] == NULL
|| memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
@@ -363,7 +361,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
if (ifa_flags)
printf("flags %02x ", ifa_flags);
if (rta_tb[IFA_LABEL])
- fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
+ fputs_stdout((char*)RTA_DATA(rta_tb[IFA_LABEL]));
if (rta_tb[IFA_CACHEINFO]) {
struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
char buf[128];
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 50acfe4e7..a23a00d87 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -88,10 +88,9 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
r->rtm_src_len
);
} else {
- fputs(format_host(r->rtm_family,
+ fputs_stdout(format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_SRC]),
- RTA_DATA(tb[RTA_SRC])),
- stdout
+ RTA_DATA(tb[RTA_SRC]))
);
}
} else if (r->rtm_src_len) {
@@ -178,7 +177,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
} else
printf("masquerade");
} else if (r->rtm_type != RTN_UNICAST)
- fputs(rtnl_rtntype_n2a(r->rtm_type), stdout);
+ fputs_stdout(rtnl_rtntype_n2a(r->rtm_type));
bb_putchar('\n');
/*fflush_all();*/
diff --git a/networking/nslookup.c b/networking/nslookup.c
index dda22de0e..c43ad46f3 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -349,6 +349,8 @@ static int parse_reply(const unsigned char *msg, size_t len)
header = (HEADER *)msg;
if (!header->aa)
printf("Non-authoritative answer:\n");
+ else if (option_mask32 & OPT_debug)
+ printf("Non-authoritative answer:\n" + 4);
if (ns_initparse(msg, len, &handle) != 0) {
//printf("Unable to parse reply: %s\n", strerror(errno));
@@ -381,7 +383,7 @@ static int parse_reply(const unsigned char *msg, size_t len)
return -1;
}
inet_ntop(AF_INET6, ns_rr_rdata(rr), astr, sizeof(astr));
- /* bind-utils-9.11.3 uses the same format for A and AAAA answers */
+ /* bind-utils 9.11.3 uses the same format for A and AAAA answers */
printf("Name:\t%s\nAddress: %s\n", ns_rr_name(rr), astr);
break;
#endif
@@ -580,7 +582,7 @@ static int send_queries(struct ns *ns)
printf("Address:\t%s\n\n",
auto_string(xmalloc_sockaddr2dotted(&ns->lsa->u.sa))
);
- /* In "Address", bind-utils-9.11.3 show port after a hash: "1.2.3.4#53" */
+ /* In "Address", bind-utils 9.11.3 show port after a hash: "1.2.3.4#53" */
/* Should we do the same? */
}
@@ -640,12 +642,26 @@ static int send_queries(struct ns *ns)
printf("*** Can't find %s: Parse error\n", G.query[qn].name);
G.exitcode = EXIT_FAILURE;
break;
-
- case 0:
- printf("*** Can't find %s: No answer\n", G.query[qn].name);
- break;
+ /* bind-utils 9.11.25 just says nothing in this case */
+ //case 0:
+ // break;
}
}
+/* NB: in case of authoritative, empty answer (NODATA), IOW: one with
+ * ns_msg_count() == 0, bind-utils 9.11.25 shows no trace of this answer
+ * (unless -debug, where it says:
+ * ------------
+ * QUESTIONS:
+ * host.com, type = AAAA, class = IN
+ * ANSWERS:
+ * AUTHORITY RECORDS:
+ * ADDITIONAL RECORDS:
+ * ------------
+ * ). Due to printing of below '\n', we do show an additional empty line.
+ * This is better than not showing any indication of this reply at all,
+ * yet maintains "compatibility". I wonder whether it's better to break compat
+ * and emit something more meaningful, e.g. print "Empty answer (NODATA)"?
+ */
bb_putchar('\n');
n_replies++;
if (n_replies >= G.query_count)
@@ -697,7 +713,7 @@ static void parse_resolvconf(void)
{
FILE *resolv;
- resolv = fopen("/etc/resolv.conf", "r");
+ resolv = fopen_for_read("/etc/resolv.conf");
if (resolv) {
char line[512]; /* "search" is defined to be up to 256 chars */
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 5a540a391..1f17b08ef 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -113,6 +113,13 @@
# define IPTOS_DSCP_AF21 0x48
#endif
+#if defined(__FreeBSD__)
+/* see sys/timex.h */
+# define adjtimex ntp_adjtime
+# define ADJ_OFFSET MOD_OFFSET
+# define ADJ_STATUS MOD_STATUS
+# define ADJ_TIMECONST MOD_TIMECONST
+#endif
/* Verbosity control (max level of -dddd options accepted).
* max 6 is very talkative (and bloated). 3 is non-bloated,
@@ -560,7 +567,7 @@ static double
gettime1900d(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL); /* never fails */
+ xgettimeofday(&tv);
G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970;
return G.cur_time;
}
@@ -1144,7 +1151,7 @@ step_time(double offset)
char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4];
time_t tval;
- gettimeofday(&tvc, NULL); /* never fails */
+ xgettimeofday(&tvc);
dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset;
d_to_tv(dtime, &tvn);
xsettimeofday(&tvn);
diff --git a/networking/ping.c b/networking/ping.c
index c4a15e06e..86d8088de 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -122,6 +122,10 @@
//usage: "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
#include <net/if.h>
+#if defined(__FreeBSD__)
+# include <netinet/in.h> /* struct ip and friends */
+# include <netinet/ip.h>
+#endif
#include <netinet/ip_icmp.h>
#include "libbb.h"
#include "common_bufsiz.h"
@@ -160,6 +164,40 @@
# endif
#endif
+#if defined(__FreeBSD__)
+/**
+ * On BSD the IPv4 struct is called struct ip and instead of iXX
+ * the members are called ip_XX. One could change this code to use
+ * struct ip but that would require to define _BSD_SOURCE and that
+ * might have other complications. Instead make sure struct iphdr
+ * is present on FreeBSD. The below is taken from GLIBC.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+struct iphdr {
+# if BYTE_ORDER == LITTLE_ENDIAN
+ unsigned int ihl:4;
+ unsigned int version:4;
+# elif BYTE_ORDER == BIG_ENDIAN
+ unsigned int version:4;
+ unsigned int ihl:4;
+# endif
+ uint8_t tos;
+ uint16_t tot_len;
+ uint16_t id;
+ uint16_t frag_off;
+ uint8_t ttl;
+ uint8_t protocol;
+ uint16_t check;
+ uint32_t saddr;
+ uint32_t daddr;
+ /*The options start here. */
+};
+#endif
+
enum {
DEFDATALEN = 56,
MAXIPLEN = 60,
diff --git a/networking/tls_fe.c b/networking/tls_fe.c
index 10971bbff..f810e112a 100644
--- a/networking/tls_fe.c
+++ b/networking/tls_fe.c
@@ -383,12 +383,10 @@ static void fe_inv__distinct(byte *r, const byte *x)
* to avoid copying temporaries.
*/
- /* 1 1 */
- fe_mul__distinct(s, x, x);
- fe_mul__distinct(r, s, x);
+ lm_copy(r, x);
- /* 1 x 248 */
- for (i = 0; i < 248; i++) {
+ /* 1, 1 x 249 */
+ for (i = 0; i < 249; i++) {
fe_mul__distinct(s, r, r);
fe_mul__distinct(r, s, x);
}
@@ -403,13 +401,11 @@ static void fe_inv__distinct(byte *r, const byte *x)
/* 0 */
fe_mul__distinct(r, s, s);
- /* 1 */
- fe_mul__distinct(s, r, r);
- fe_mul__distinct(r, s, x);
-
- /* 1 */
- fe_mul__distinct(s, r, r);
- fe_mul__distinct(r, s, x);
+ /* 1, 1 */
+ for (i = 0; i < 2; i++) {
+ fe_mul__distinct(s, r, r);
+ fe_mul__distinct(r, s, x);
+ }
}
#if 0 //UNUSED
@@ -435,12 +431,10 @@ static void exp2523(byte *r, const byte *x, byte *s)
* 111111... 01
*/
- /* 1 1 */
- fe_mul__distinct(r, x, x);
- fe_mul__distinct(s, r, x);
+ lm_copy(s, x);
- /* 1 x 248 */
- for (i = 0; i < 248; i++) {
+ /* 1, 1 x 249 */
+ for (i = 0; i < 249; i++) {
fe_mul__distinct(r, s, s);
fe_mul__distinct(s, r, x);
}
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 3f1a9ab46..057f8591a 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -505,7 +505,7 @@ send_probe(int seq, int ttl)
struct outdata6_t *pkt = (void *) outdata;
pkt->ident6 = ident;
pkt->seq6 = htonl(seq);
- /*gettimeofday(&pkt->tv, &tz);*/
+ /*xgettimeofday(&pkt->tv);*/
icp = outicmp6;
} else
#endif
@@ -716,8 +716,8 @@ packet4_ok(int read_len, int seq)
// Off: since we do not form the entire IP packet,
// but defer it to kernel, we can't set source port,
// and thus can't check it here in the reply
- /* && up->source == ident */
- && up->dest == htons(port + seq)
+ /* && up->uh_sport == ident */
+ && up->uh_dport == htons(port + seq)
) {
return (type == ICMP_TIMXCEED ? -1 : code + 1);
}
@@ -896,7 +896,7 @@ traceroute_init(int op, char **argv)
op |= getopt32(argv, "^"
OPT_STRING
- "\0" "-1:x-x" /* minimum 1 arg */
+ "\0" "-1" /* minimum 1 arg */
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str
);
@@ -985,8 +985,13 @@ traceroute_init(int op, char **argv)
snd = xsocket(AF_INET, SOCK_DGRAM, 0);
}
#if ENABLE_TRACEROUTE6
+# if defined(__FreeBSD__)
+# define SOL_V6_OPTION SOL_IPV6
+# else
+# define SOL_V6_OPTION SOL_RAW
+# endif
else {
- if (setsockopt_int(rcvsock, SOL_RAW, IPV6_CHECKSUM, 2) != 0)
+ if (setsockopt_int(rcvsock, SOL_V6_OPTION, IPV6_CHECKSUM, 2) != 0)
bb_perror_msg_and_die("setsockopt(%s)", "IPV6_CHECKSUM");
if (op & OPT_USE_ICMP)
snd = xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 7d04bb246..8c8c11c26 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -104,6 +104,14 @@ INSERT
comment "Common options for DHCP applets"
depends on UDHCPD || UDHCPC || UDHCPC6 || DHCPRELAY
+config UDHCPC_DEFAULT_INTERFACE
+ string "Default interface name"
+ default "eth0"
+ depends on UDHCPC || UDHCPC6
+ help
+ The interface that will be used if no other interface is
+ specified on the commandline.
+
config FEATURE_UDHCP_PORT
bool "Enable '-P port' option for udhcpd and udhcpc"
default n
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index d4d29dcbb..fbdaa99bd 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -1163,7 +1163,7 @@ static void client_background(void)
//usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"odR] [-i IFACE] [-r IPv6] [-s PROG] [-p PIDFILE]\n"
//usage: " [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P PORT]")
//usage:#define udhcpc6_full_usage "\n"
-//usage: "\n -i IFACE Interface to use (default eth0)"
+//usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
//usage: "\n -p FILE Create pidfile"
//usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
//usage: "\n -B Request broadcast replies"
@@ -1231,7 +1231,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* Default options */
IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;)
IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;)
- client_data.interface = "eth0";
+ client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE;
client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
client_data.sockfd = -1;
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 98720b45b..922c71ebd 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1196,7 +1196,7 @@ static void client_background(void)
//usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
//usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
//usage:#define udhcpc_full_usage "\n"
-//usage: "\n -i IFACE Interface to use (default eth0)"
+//usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
//usage: IF_FEATURE_UDHCP_PORT(
//usage: "\n -P PORT Use PORT (default 68)"
//usage: )
@@ -1265,7 +1265,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* Default options */
IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
- client_data.interface = "eth0";
+ client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE;
client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
client_data.sockfd = -1;
str_V = "udhcp "BB_VER;
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index 1e9405205..19606c58e 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -112,7 +112,7 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
printf("%02u:%02u:%02u\n", h, m, (unsigned)expires);
} else { /* -a */
time_t t = expires_abs;
- fputs(ctime(&t), stdout);
+ fputs_stdout(ctime(&t));
}
}
/* close(fd); */
diff --git a/procps/nmeter.c b/procps/nmeter.c
index 07b7abe2f..f08938654 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -952,11 +952,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
reset_outbuf();
if (G.delta >= 0) {
- gettimeofday(&G.tv, NULL);
+ xgettimeofday(&G.tv);
usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz);
}
- gettimeofday(&G.start, NULL);
+ xgettimeofday(&G.start);
G.tv = G.start;
while (1) {
collect_info(first);
@@ -971,7 +971,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
if (G.delta >= 0) {
int rem;
// can be commented out, will sacrifice sleep time precision a bit
- gettimeofday(&G.tv, NULL);
+ xgettimeofday(&G.tv);
if (need_seconds)
rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz;
else
@@ -983,7 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
}
usleep(rem);
}
- gettimeofday(&G.tv, NULL);
+ xgettimeofday(&G.tv);
}
/*return 0;*/
diff --git a/procps/pmap.c b/procps/pmap.c
index 9e541c707..408cbfce7 100644
--- a/procps/pmap.c
+++ b/procps/pmap.c
@@ -27,20 +27,14 @@
#include "libbb.h"
-#if ULONG_MAX == 0xffffffff
+#if ULLONG_MAX == 0xffffffff
# define TABS "\t"
-# define AFMT "8"
+# define AFMTLL "8"
# define DASHES ""
#else
# define TABS "\t\t"
-# define AFMT "16"
-# define DASHES "--------"
-#endif
-
-#if ULLONG_MAX == 0xffffffff
-# define AFMTLL "8"
-#else
# define AFMTLL "16"
+# define DASHES "--------"
#endif
enum {
diff --git a/procps/powertop.c b/procps/powertop.c
index d508b5f78..fc6018b7a 100644
--- a/procps/powertop.c
+++ b/procps/powertop.c
@@ -818,7 +818,7 @@ int powertop_main(int argc UNUSED_PARAM, char UNUSED_PARAM **argv)
for (i = 0; i < MAX_CSTATE_COUNT + 2; i++)
if (cstate_lines[i][0])
- fputs(cstate_lines[i], stdout);
+ fputs_stdout(cstate_lines[i]);
i = process_timer_stats();
#if ENABLE_FEATURE_POWERTOP_PROCIRQ
diff --git a/procps/top.c b/procps/top.c
index 8d39526ff..cadc4ecec 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -712,7 +712,7 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width)
);
if ((int)(scr_width - col) > 1)
read_cmdline(line_buf + col, scr_width - col, s->pid, s->comm);
- fputs(line_buf, stdout);
+ fputs_stdout(line_buf);
/* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu,
cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */
s++;
diff --git a/runit/runsv.c b/runit/runsv.c
index d395d4528..ecab8cdf5 100644
--- a/runit/runsv.c
+++ b/runit/runsv.c
@@ -62,12 +62,12 @@ static void gettimeofday_ns(struct timespec *ts)
&& sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec)
) {
/* Cheat */
- gettimeofday((void*)ts, NULL);
+ xgettimeofday((void*)ts);
ts->tv_nsec *= 1000;
} else {
/* For example, musl has "incompatible" layouts */
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000;
}
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 040e71104..294e31aca 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -351,7 +351,7 @@ static void fmt_time_human_30nul(char *s, char dt_delim)
struct tm *ptm;
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
ptm = gmtime_r(&tv.tv_sec, &tm);
/* ^^^ using gmtime_r() instead of gmtime() to not use static data */
sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000",
@@ -376,7 +376,7 @@ static void fmt_time_bernstein_25(char *s)
struct timeval tv;
unsigned sec_hi;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32;
tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec;
tv.tv_usec *= 1000;
diff --git a/scripts/bb_release b/scripts/bb_release
index 2e146bf84..545440d3a 100755
--- a/scripts/bb_release
+++ b/scripts/bb_release
@@ -8,6 +8,7 @@
#svn co svn://busybox.net/trunk/busybox
cd busybox || { echo "cd busybox failed"; exit 1; }
+chmod -Rc u+w,a+rX,go-w .
make release || { echo "make release failed"; exit 1; }
cd ..
diff --git a/shell/ash.c b/shell/ash.c
index f16d7fb6a..1aead6df4 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -314,9 +314,12 @@ typedef long arith_t;
/* ============ Shell options */
+/* If you add/change options hare, update --help text too */
static const char *const optletters_optnames[] = {
"e" "errexit",
"f" "noglob",
+/* bash has '-o ignoreeof', but no short synonym -I for it */
+/* (in bash, set -I disables invisible variables (what's that?)) */
"I" "ignoreeof",
/* The below allowed this invocation:
* ash -c 'set -i; echo $-; sleep 5; echo $-'
@@ -325,9 +328,10 @@ static const char *const optletters_optnames[] = {
* In our code, this is denoted by empty long name:
*/
"i" "",
+/* (removing "i" altogether would remove it from "$-", not good) */
"m" "monitor",
"n" "noexec",
-/* Ditto: bash has no "set -s" */
+/* Ditto: bash has no "set -s", "set -c" */
"s" "",
"c" "",
"x" "xtrace",
@@ -7011,7 +7015,8 @@ subevalvar(char *start, char *str, int strloc,
slash_pos = -1;
if (repl) {
slash_pos = expdest - ((char *)stackblock() + strloc);
- STPUTC('/', expdest);
+ if (!(flag & EXP_DISCARD))
+ STPUTC('/', expdest);
//bb_error_msg("repl+1:'%s'", repl + 1);
p = argstr(repl + 1, (flag & EXP_DISCARD) | EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */
*repl = '/';
@@ -7173,7 +7178,7 @@ subevalvar(char *start, char *str, int strloc,
len = 0;
idx = startp;
end = str - 1;
- while (idx < end) {
+ while (idx <= end) {
try_to_match:
loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
//bb_error_msg("scanright('%s'):'%s'", str, loc);
@@ -7181,6 +7186,8 @@ subevalvar(char *start, char *str, int strloc,
/* No match, advance */
char *restart_detect = stackblock();
skip_matching:
+ if (idx >= end)
+ break;
STPUTC(*idx, expdest);
if (quotes && (unsigned char)*idx == CTLESC) {
idx++;
@@ -7193,8 +7200,6 @@ subevalvar(char *start, char *str, int strloc,
len++;
rmesc++;
/* continue; - prone to quadratic behavior, smarter code: */
- if (idx >= end)
- break;
if (str[0] == '*') {
/* Pattern is "*foo". If "*foo" does not match "long_string",
* it would never match "ong_string" etc, no point in trying.
@@ -11371,10 +11376,10 @@ static void FAST_FUNC
change_epoch(struct var *vepoch, const char *fmt)
{
struct timeval tv;
- char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3];
+ char buffer[sizeof("%llu.nnnnnn") + sizeof(long long)*3];
- gettimeofday(&tv, NULL);
- sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec);
+ xgettimeofday(&tv);
+ sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec);
setvar(vepoch->var_text, buffer, VNOFUNC);
vepoch->flags &= ~VNOFUNC;
}
@@ -11382,13 +11387,13 @@ change_epoch(struct var *vepoch, const char *fmt)
static void FAST_FUNC
change_seconds(const char *value UNUSED_PARAM)
{
- change_epoch(&vepochs, "%lu");
+ change_epoch(&vepochs, "%llu");
}
static void FAST_FUNC
change_realtime(const char *value UNUSED_PARAM)
{
- change_epoch(&vepochr, "%lu.%06u");
+ change_epoch(&vepochr, "%llu.%06u");
}
#endif
@@ -14265,7 +14270,8 @@ init(void)
//usage:#define ash_trivial_usage
-//usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
+//usage: "[-il] [-/+Cabefmnuvx] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
+//////// comes from ^^^^^^^^^^optletters
//usage:#define ash_full_usage "\n\n"
//usage: "Unix shell interpreter"
@@ -14312,9 +14318,9 @@ procargs(char **argv)
}
if (mflag == 2)
mflag = iflag;
+ /* Unset options which weren't explicitly set or unset */
for (i = 0; i < NOPTS; i++)
- if (optlist[i] == 2)
- optlist[i] = 0;
+ optlist[i] &= 1; /* same effect as "if (optlist[i] == 2) optlist[i] = 0;" */
#if DEBUG == 2
debug = 1;
#endif
@@ -14499,7 +14505,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
if (sflag || minusc == NULL) {
#if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
- if (iflag) {
+ if (line_input_state) {
const char *hp = lookupvar("HISTFILE");
if (!hp) {
hp = lookupvar("HOME");
@@ -14513,7 +14519,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
}
}
if (hp)
- line_input_state->hist_file = hp;
+ line_input_state->hist_file = xstrdup(hp);
# if ENABLE_FEATURE_SH_HISTFILESIZE
hp = lookupvar("HISTFILESIZE");
line_input_state->max_history = size_from_HISTFILESIZE(hp);
diff --git a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right
index 892916783..a8d1a3bef 100644
--- a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right
+++ b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right
@@ -1,2 +1,3 @@
+w
Ok:0
diff --git a/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests b/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests
index 73a43d38e..22aaba560 100755
--- a/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests
+++ b/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests
@@ -1,3 +1,5 @@
+unset v
+echo ${v/*/w}
v=''
echo ${v/*/w}
echo Ok:$?
diff --git a/shell/hush.c b/shell/hush.c
index 9fead37da..5eb6fa396 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1027,7 +1027,7 @@ struct globals {
struct sigaction sa;
char optstring_buf[sizeof("eixcs")];
#if BASH_EPOCH_VARS
- char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
+ char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3];
#endif
#if ENABLE_FEATURE_EDITING
char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
@@ -2277,13 +2277,13 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
{
const char *fmt = NULL;
if (strcmp(name, "EPOCHSECONDS") == 0)
- fmt = "%lu";
+ fmt = "%llu";
else if (strcmp(name, "EPOCHREALTIME") == 0)
- fmt = "%lu.%06u";
+ fmt = "%llu.%06u";
if (fmt) {
struct timeval tv;
- gettimeofday(&tv, NULL);
- sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec,
+ xgettimeofday(&tv);
+ sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec,
(unsigned)tv.tv_usec);
return G.epoch_buf;
}
@@ -2692,7 +2692,7 @@ static int get_user_input(struct in_str *i)
* Without check_and_run_traps, handler never runs.
*/
check_and_run_traps();
- fputs(prompt_str, stdout);
+ fputs_stdout(prompt_str);
fflush_all();
}
r = hfgetc(i->file);
@@ -10163,7 +10163,8 @@ int hush_main(int argc, char **argv)
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
while (1) {
- int opt = getopt(argc, argv, "+cexinsl"
+ int opt = getopt(argc, argv, "+" /* stop at 1st non-option */
+ "cexinsl"
#if !BB_MMU
"<:$:R:V:"
# if ENABLE_HUSH_FUNCTIONS
@@ -10255,12 +10256,13 @@ int hush_main(int argc, char **argv)
}
# endif
#endif
- case 'n':
- case 'x':
- case 'e':
+ /*case '?': invalid option encountered (set_mode('?') will fail) */
+ /*case 'n':*/
+ /*case 'x':*/
+ /*case 'e':*/
+ default:
if (set_mode(1, opt, NULL) == 0) /* no error */
break;
- default:
bb_show_usage();
}
} /* option parsing loop */
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index c0ec1c0bf..82596bc0b 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -100,7 +100,7 @@ static void klogd_close(void)
#else
# ifndef _PATH_KLOG
-# ifdef __GNU__
+# if defined(__GNU__) || defined (__FreeBSD__)
# define _PATH_KLOG "/dev/klog"
# else
# error "your system's _PATH_KLOG is unknown"
diff --git a/sysklogd/logread.c b/sysklogd/logread.c
index b52dc9cac..d5f8ca0a2 100644
--- a/sysklogd/logread.c
+++ b/sysklogd/logread.c
@@ -205,7 +205,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv)
cur = shbuf_tail;
#else
while (cur != shbuf_tail) {
- fputs(shbuf_data + cur, stdout);
+ fputs_stdout(shbuf_data + cur);
cur += strlen(shbuf_data + cur) + 1;
if (cur >= shbuf_size)
cur = 0;
@@ -217,7 +217,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv)
#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
for (i = 0; i < len_total; i += strlen(copy + i) + 1) {
- fputs(copy + i, stdout);
+ fputs_stdout(copy + i);
}
free(copy);
#endif
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 598f28d0c..6ddfd771a 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -842,7 +842,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
#if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS
if (!timestamp) {
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
now = tv.tv_sec;
timestamp = ctime(&now) + 4; /* skip day of week */
/* overwrite year by milliseconds, zero terminate */
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index 92c83d719..cf9b722dc 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -383,6 +383,11 @@ testing "awk errors on missing delete arg" \
"awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" ""
SKIP=
+optional FEATURE_AWK_GNU_EXTENSIONS
+testing "awk printf('%c') can output NUL" \
+ "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n"
+SKIP=
+
# testing "description" "command" "result" "infile" "stdin"
testing 'awk negative field access' \
'awk 2>&1 -- '\''{ $(-1) }'\' \
diff --git a/testsuite/cat.tests b/testsuite/cat.tests
index 10970dc90..cf924ab5b 100755
--- a/testsuite/cat.tests
+++ b/testsuite/cat.tests
@@ -22,4 +22,28 @@ testing 'cat -v' \
'foo\n'
SKIP=
+optional FEATURE_CATN
+testing 'cat -n' \
+ 'cat -n' \
+"\
+ 1 line 1
+ 2
+ 3 line 3
+" \
+ '' \
+ 'line 1\n\nline 3\n'
+SKIP=
+
+optional FEATURE_CATN
+testing 'cat -b' \
+ 'cat -b' \
+"\
+ 1 line 1
+
+ 2 line 3
+" \
+ '' \
+ 'line 1\n\nline 3\n'
+SKIP=
+
exit $FAILCOUNT
diff --git a/testsuite/dc_add_results.txt b/testsuite/dc_add_results.txt
index 542a62ea3..2d955935f 100644
--- a/testsuite/dc_add_results.txt
+++ b/testsuite/dc_add_results.txt
@@ -9,9 +9,9 @@
1998
324869359109479
2378639108055453348401
-78562139406792834691802347619083467219846713490861872324967138636055\
-45508706362018540498696043776980521464405852627147161556994835657433\
-00967298
+785621394067928346918023476190834672198467134908618723249671386360554\
+550870636201854049869604377698052146440585262714716155699483565743300\
+967298
1.1
1.1
37842935130118.1187478621432354
@@ -20,21 +20,21 @@
-2
-19
-1287904651762470260258
-100000000000000000000000000000000000000000000000000000000000.0000000\
-00000000000000000000000000000000000000000000000000000000000000000000\
-000000000000000000000000000000000000000000000
-100000000000000000000000000000000000000000000000000000000000.0000000\
-00000000000000000000000000000000000000000000000000000000000000000000\
-000000000000000000000000000000000000000000000
-100000000000000000000000000000000000000000000000000000000000.0000000\
-00000000000000000000000000000000000000000000000000000000000000000000\
-000000000000000000000000000000000000000009999
-99999999999999999999999999999999999999999999999999999999999.99999999\
-99999999999999999999999999999999999999999999999999000000000000000000\
-00000000000000000000000000000000000000009999
-99999999999999999999999999999999999990000000000000000000000.00000000\
-00000000000000000000000000000000000000000000000000000000000000000000\
-00000000000000000000000000000000000000009999
+100000000000000000000000000000000000000000000000000000000000.00000000\
+000000000000000000000000000000000000000000000000000000000000000000000\
+0000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.00000000\
+000000000000000000000000000000000000000000000000000000000000000000000\
+0000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.00000000\
+000000000000000000000000000000000000000000000000000000000000000000000\
+0000000000000000000000000000000000000009999
+99999999999999999999999999999999999999999999999999999999999.999999999\
+999999999999999999999999999999999999999999999999900000000000000000000\
+000000000000000000000000000000000000009999
+99999999999999999999999999999999999990000000000000000000000.000000000\
+000000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000009999
122761518
-14338.391079082
-2422295.6865057444
diff --git a/testsuite/dc_decimal_results.txt b/testsuite/dc_decimal_results.txt
index 275d431c6..66bb91ac3 100644
--- a/testsuite/dc_decimal_results.txt
+++ b/testsuite/dc_decimal_results.txt
@@ -9,19 +9,17 @@
123
7505
1023468723275435238491972521917846
-43434724324317058673920735170382703980273527090273892739207390379379\
-60379637893607893607893670530278200795207952702873892786172916728961\
-78390789360741897358785738607967926792673752073092537298378279365279\
-3
+434347243243170586739207351703827039802735270902738927392073903793796\
+037963789360789360789367053027820079520795270287389278617291672896178\
+3907893607418973587857386079679267926737520730925372983782793652793
-1
-203
-57
-18586
-31378682943772818461924738352952347258
--8239456287456735894950672387239865203756982376208346745096273452730\
-96287563846592384526349872634895763257893467523987578690283762897568\
-45907234875807107108781350187590812735901871502384171023987230138727\
-8
+-82394562874567358949506723872398652037569823762083467450962734527309\
+628756384659238452634987263489576325789346752398757869028376289756845\
+9072348758071071087813501875908127359018715023841710239872301387278
.123521346523546
.1245923756273856
-.1024678456387
@@ -31,21 +29,21 @@
234237468293576.000000000000000000000000000000
23987623568943567.00000000000000000005677834650000000000000
23856934568940675.000000000000000435676782300000000000000456784
-77567648698496.00000000000000000058767475000000000045856380000000000\
-0000
-2348672354968723.237482354600000000000325698739450234689243562387000\
-0000034578
+77567648698496.000000000000000000587674750000000000458563800000000000\
+000
+2348672354968723.2374823546000000000003256987394502346892435623870000\
+000034578
-2354768.000000000000000000000000000000000000
-96739874567.000000000347683456
-3764568345.000000000004573845000000347683460
-356784356.934568495770004586495678300000000
-74325437345273852773827101738273127312738521733017537073520735207307\
-570358738257390761276072160719802671980267018728630178.7082681027680\
-52176021786784127612768127086782782176817317820783071097801773817867\
-8012767377058785378278207385237085237803278203782037237582795870
--7567527327852738512737285378527382578372836789657385273852729836783\
-72867327835672967385278372637862738627836279863782673862783670.71738\
-17836173871836718637861073861783678160376017836701860376017810773527\
-8372832783728367826738627836278378260736270367362073867097307925
-9812734012837410982345719208345712908357412903587192048571920458712.\
-23957182459817249058172945781
+743254373452738527738271017382731273127385217330175370735207352073075\
+70358738257390761276072160719802671980267018728630178.708268102768052\
+176021786784127612768127086782782176817317820783071097801773817867801\
+2767377058785378278207385237085237803278203782037237582795870
+-75675273278527385127372853785273825783728367896573852738527298367837\
+2867327835672967385278372637862738627836279863782673862783670.7173817\
+836173871836718637861073861783678160376017836701860376017810773527837\
+2832783728367826738627836278378260736270367362073867097307925
+9812734012837410982345719208345712908357412903587192048571920458712.2\
+3957182459817249058172945781
diff --git a/testsuite/dc_divmod_results.txt b/testsuite/dc_divmod_results.txt
index c55e9303d..ee91ee88c 100644
--- a/testsuite/dc_divmod_results.txt
+++ b/testsuite/dc_divmod_results.txt
@@ -58,8 +58,8 @@
100864416620775.31076855630746548983
-53336.193401942302558132911110799109649707477
.00000000052530099381
-.0000000000000000000000000000000000000000000000000000000000000001907\
-266929376630027064745963897
+.00000000000000000000000000000000000000000000000000000000000000019072\
+66929376630027064745963897
42612515855353136519261264261472677699404182.78776061098893912189
0
0
@@ -121,6 +121,6 @@
100864416620775
-3878923750692883.7238596702834756902
0
-.0000000000000000000000000000000000000000000184866017689020776005643\
-3621086
+.00000000000000000000000000000000000000000001848660176890207760056433\
+621086
42612515855353136519261264261472677699404182
diff --git a/testsuite/dc_multiply_results.txt b/testsuite/dc_multiply_results.txt
index 9666059a5..aaf3a20fc 100644
--- a/testsuite/dc_multiply_results.txt
+++ b/testsuite/dc_multiply_results.txt
@@ -15,8 +15,8 @@
3543531533584430580556128344529291738
568600835566479683035874339053.4411638427543228060
7487566285885.8557453089005171423976251098
-373846412427291014394738378015501363938345620046.7869650248829232267\
-2297002026819
+373846412427291014394738378015501363938345620046.78696502488292322672\
+297002026819
-1
-2
-2751507058396910892
diff --git a/testsuite/dc_power_results.txt b/testsuite/dc_power_results.txt
index 997f44f59..dc5d56766 100644
--- a/testsuite/dc_power_results.txt
+++ b/testsuite/dc_power_results.txt
@@ -10,15 +10,15 @@
18927361346
.23523785962738592635777
328956734869213746.89782398457234
-16473742664221279051571200630760751138799221376964991600670000200609\
-08006052596520320731708604393844468006290371918262741885989163144389\
-39367835091560809036359941703341471396407660150658436796925310445979\
-21333166245765946557344383284626113908419359990042883048537750217279\
-17481980123593363177308481941550382845381799410533956718500484099889\
-610805653325917409549921909941664118421333562129
+164737426642212790515712006307607511387992213769649916006700002006090\
+800605259652032073170860439384446800629037191826274188598916314438939\
+367835091560809036359941703341471396407660150658436796925310445979213\
+331662457659465573443832846261139084193599900428830485377502172791748\
+198012359336317730848194155038284538179941053395671850048409988961080\
+5653325917409549921909941664118421333562129
0
-43287877285033571298394739716218787350087163435619825150259705419.98\
-016445740928054425
+43287877285033571298394739716218787350087163435619825150259705419.980\
+16445740928054425
1.00000000000000000000
.50000000000000000000
.10000000000000000000
@@ -31,27 +31,27 @@
1
-2
4
-14997322375665265051328725757939209353051902095893907150382724666290\
-49749481660976421019742616298227588464420182758442163654172400528243\
-00885441207762486233574213374503090372518590691583139696652847404883\
-08573912261119588874308960204159666762789603037188471170006223907416\
-60492840269152716750700089148882139254399347568222390231015487895905\
-73727080561379177721440905866857248917982113340543176658480139248897\
-54802503253413282808814063861470711399810899724515727713334909764746\
-27910290211411231279325882505708287941671508154740003122373284699097\
-78346501539634198926772266511968381368929692275950529960923432771985\
-12597189390708050983487158873301681237787429436264801751664042999180\
-3448659818912436089
-11478830555358864333472551120140548480416206583184496764727387456058\
-792742209537931243951391229607936
+149973223756652650513287257579392093530519020958939071503827246662904\
+974948166097642101974261629822758846442018275844216365417240052824300\
+885441207762486233574213374503090372518590691583139696652847404883085\
+739122611195888743089602041596667627896030371884711700062239074166049\
+284026915271675070008914888213925439934756822239023101548789590573727\
+080561379177721440905866857248917982113340543176658480139248897548025\
+032534132828088140638614707113998108997245157277133349097647462791029\
+021141123127932588250570828794167150815474000312237328469909778346501\
+539634198926772266511968381368929692275950529960923432771985125971893\
+907080509834871588733016812377874294362648017516640429991803448659818\
+912436089
+114788305553588643334725511201405484804162065831844967647273874560587\
+92742209537931243951391229607936
-.00000000000000017759
--2067373624686414405470850679965010694114490999957199847684803894306\
-56243666149296582304582679590231948238805965642713928910384741502707\
-.23224479257866798694
-11606078892843496082360561256965139908586179418605021706789617179085\
-85768049299693425729565480314913006780973928345684673490252494674985\
-0186164225375953066263609289359900615361965737717208159874390.293769\
-70206344604971
+-20673736246864144054708506799650106941144909999571998476848038943065\
+6243666149296582304582679590231948238805965642713928910384741502707.2\
+3224479257866798694
+116060788928434960823605612569651399085861794186050217067896171790858\
+576804929969342572956548031491300678097392834568467349025249467498501\
+86164225375953066263609289359900615361965737717208159874390.293769702\
+06344604971
-1.00000000000000000000
1.00000000000000000000
-.50000000000000000000
@@ -59,14 +59,14 @@
0
0
-.00000000000002874159
--1945134149489344891879057554905782841936258356736314337975569799825\
-94091939572752348215929683891336730843553721422164737465108229034947\
-87333189564755763444242676978610321731298729194092653999616928308494\
-26419468484566422775668903315088810746121307679948574976162519479931\
-18935243698160094347216562490000767121041786977792546155155934655909\
-14123833869470494708767968978717730012864171105540029928688274136791\
-98175053824022144065005509214813689232148489884560100200475909009813\
-340098100705258138.98542904577525702068
+-19451341494893448918790575549057828419362583567363143379755697998259\
+409193957275234821592968389133673084355372142216473746510822903494787\
+333189564755763444242676978610321731298729194092653999616928308494264\
+194684845664227756689033150888107461213076799485749761625194799311893\
+524369816009434721656249000076712104178697779254615515593465590914123\
+833869470494708767968978717730012864171105540029928688274136791981750\
+538240221440650055092148136892321484898845601002004759090098133400981\
+00705258138.98542904577525702068
0
0
0
diff --git a/testsuite/dc_subtract_results.txt b/testsuite/dc_subtract_results.txt
index 9f7726254..0a9762381 100644
--- a/testsuite/dc_subtract_results.txt
+++ b/testsuite/dc_subtract_results.txt
@@ -8,15 +8,15 @@
2874519803456326214611
9000000000000000000000000000000000000001
1
-9000000000000000000000000000000000000000.000000000000000000000000000\
-00000001
+9000000000000000000000000000000000000000.0000000000000000000000000000\
+0000001
.0000000000000000000000000000000001
-9999999999999999999999999999999999999999.999999999999999999999999999\
+9999999999999999999999999999999999999999.9999999999999999999999999999\
+9999999999999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.999999999999999999999999999\
99999999999999999999999999999999999999999999999999999999999
-10000000000000000000000000000000000000000.99999999999999999999999999\
-999999999999999999999999999999999999999999999999999999999999
-10000000000000000000000000000000000000000.00000000009999999999999999\
-99999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.000000000099999999999999999\
+9999999999999999999999999999999999999999999999999
-8
-182934721309467230894628759280719690
1245723576605103923392087218483
diff --git a/testsuite/nl.tests b/testsuite/nl.tests
new file mode 100755
index 000000000..95e7abb58
--- /dev/null
+++ b/testsuite/nl.tests
@@ -0,0 +1,39 @@
+#!/bin/sh
+# Copyright 2021 by Ron Yorston
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+. ./testing.sh
+
+# testing "test name" "commands" "expected result" "file input" "stdin"
+
+testing "nl numbers all lines" \
+ "nl -b a input" \
+"\
+ 1 line 1
+ 2
+ 3 line 3
+" \
+ "line 1\n\nline 3\n" \
+ ""
+
+testing "nl numbers non-empty lines" \
+ "nl -b t input" \
+"\
+ 1 line 1
+
+ 2 line 3
+" \
+ "line 1\n\nline 3\n" \
+ ""
+
+testing "nl numbers no lines" \
+ "nl -b n input" \
+"\
+ line 1
+
+ line 3
+" \
+ "line 1\n\nline 3\n" \
+ ""
+
+exit $FAILCOUNT
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c
index e884e3dc1..4c30f31f8 100644
--- a/util-linux/fdisk_gpt.c
+++ b/util-linux/fdisk_gpt.c
@@ -87,7 +87,7 @@ gpt_print_wide36(uint16_t *s)
}
wc[i] = 0;
if (wcstombs(buf, wc, sizeof(buf)) <= sizeof(buf)-1)
- fputs(printable_string(buf), stdout);
+ fputs_stdout(printable_string(buf));
#else
char buf[37];
int i = 0;
@@ -98,7 +98,7 @@ gpt_print_wide36(uint16_t *s)
i++;
}
buf[i] = '\0';
- fputs(buf, stdout);
+ fputs_stdout(buf);
#endif
}
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 25db7cdad..723b09589 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -79,7 +79,7 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc)
int before = tm_time.tm_sec;
while (1) {
rtc_read_tm(&tm_time, fd);
- gettimeofday(sys_tv, NULL);
+ xgettimeofday(sys_tv);
if (before != (int)tm_time.tm_sec)
break;
}
@@ -205,7 +205,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
int rtc;
rtc = rtc_xopen(pp_rtcname, O_WRONLY);
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
/* Prepare tm_time */
if (sizeof(time_t) == sizeof(tv.tv_sec)) {
if (utc)
@@ -253,7 +253,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
unsigned rem_usec;
time_t t;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
t = tv.tv_sec;
rem_usec = 1000000 - tv.tv_usec;
@@ -274,7 +274,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
}
/* gmtime/localtime took some time, re-get cur time */
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
if (tv.tv_sec < t /* we are still in old second */
|| (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index ebf83d1a3..dbbcbc655 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -963,7 +963,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
static char *curtime(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
sprintf(
strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec),
".%06u",
diff --git a/util-linux/rev.c b/util-linux/rev.c
index ede4fbc9c..d439b4da8 100644
--- a/util-linux/rev.c
+++ b/util-linux/rev.c
@@ -108,7 +108,7 @@ int rev_main(int argc UNUSED_PARAM, char **argv)
#else
strrev(buf, strlen(buf));
#endif
- fputs(buf, stdout);
+ fputs_stdout(buf);
}
fclose(fp);
} while (*argv);
diff --git a/util-linux/script.c b/util-linux/script.c
index 4eac5e94f..963435335 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -172,7 +172,7 @@ int script_main(int argc UNUSED_PARAM, char **argv)
struct timeval tv;
double newtime;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
fprintf(timing_fp, "%f %u\n", newtime - oldtime, count);
oldtime = newtime;