From 33745b1fc8cc6d41f4e708d67800d296668af2ce Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 18 Feb 2021 13:44:27 +0100 Subject: ash: placate -Werror=format-security "In function 'sprint_status48': error: format not a string literal and no format arguments" function old new delta sprint_status48 160 158 -2 Signed-off-by: Denys Vlasenko --- include/platform.h | 8 ++++++++ libbb/platform.c | 12 ++++++++++++ shell/ash.c | 4 +--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/platform.h b/include/platform.h index d991f3140..24efd186b 100644 --- a/include/platform.h +++ b/include/platform.h @@ -407,6 +407,7 @@ typedef unsigned smalluint; #define HAVE_SETBIT 1 #define HAVE_SIGHANDLER_T 1 #define HAVE_STPCPY 1 +#define HAVE_STPNCPY 1 #define HAVE_MEMPCPY 1 #define HAVE_STRCASESTR 1 #define HAVE_STRCHRNUL 1 @@ -442,6 +443,7 @@ typedef unsigned smalluint; # undef HAVE_MKDTEMP # undef HAVE_SETBIT # undef HAVE_STPCPY +# undef HAVE_STPNCPY # undef HAVE_STRCASESTR # undef HAVE_STRCHRNUL # undef HAVE_STRSEP @@ -514,6 +516,7 @@ typedef unsigned smalluint; #if defined(__digital__) && defined(__unix__) # undef HAVE_STPCPY +# undef HAVE_STPNCPY #endif #if defined(ANDROID) || defined(__ANDROID__) @@ -530,6 +533,7 @@ typedef unsigned smalluint; # undef HAVE_TTYNAME_R # undef HAVE_GETLINE # undef HAVE_STPCPY +# undef HAVE_STPNCPY # endif # undef HAVE_MEMPCPY # undef HAVE_STRCHRNUL @@ -574,6 +578,10 @@ typedef void (*sighandler_t)(int); extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; #endif +#ifndef HAVE_STPNCPY +extern char *stpncpy(char *p, const char *to_add, size_t n) FAST_FUNC; +#endif + #ifndef HAVE_MEMPCPY #include /* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have diff --git a/libbb/platform.c b/libbb/platform.c index 329b0237e..7913353e2 100644 --- a/libbb/platform.c +++ b/libbb/platform.c @@ -166,6 +166,18 @@ char* FAST_FUNC stpcpy(char *p, const char *to_add) } #endif +#ifndef HAVE_STPNCPY +char* FAST_FUNC stpncpy(char *p, const char *to_add, size_t n) +{ + while (n != 0 && (*p = *to_add) != '\0') { + p++; + to_add++; + n--; + } + return p; +} +#endif + #ifndef HAVE_GETLINE ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) { diff --git a/shell/ash.c b/shell/ash.c index 1aead6df4..6a16833b1 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4263,9 +4263,7 @@ sprint_status48(char *os, int status, int sigonly) #endif } st &= 0x7f; -//TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata - //s = stpncpy(s, strsignal(st), 32); //not all libc have stpncpy() - s += fmtstr(s, 32, strsignal(st)); + s = stpncpy(s, strsignal(st), 32); if (WCOREDUMP(status)) { s = stpcpy(s, " (core dumped)"); } -- cgit v1.2.3 From 6bdfbc4cb5470f63d4905e89f89a9829af354316 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 18 Feb 2021 23:30:24 +0100 Subject: libbb: fix '--help' handling in FEATURE_SH_NOFORK=y Most BusyBox applets respond to the '--help' option by printing a usage message. This is normally handled by busybox_main() so applet main routines don't have support for '--help'. In standalone shell mode with FEATURE_SH_NOFORK enabled nofork applets are invoked directly, bypassing busybox_main(). This results in inconsistent handling of '--help': - applets which call getopt() report "unrecognized option '--help'" and print help anyway; - realpath says "--help: No such file or directory" and doesn't print help; - usleep says "invalid number '--help'" and doesn't print help. Avoid inconsistency by checking for '--help' in run_nofork_applet(). Bug found by Ron Yorston. function old new delta show_usage_if_dash_dash_help - 70 +70 run_nofork_applet 347 362 +15 run_applet_no_and_exit 432 365 -67 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 85/-67) Total: 18 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/appletlib.c | 29 +++++++++++++++++++---------- libbb/vfork_daemon_rexec.c | 5 +++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 135d9111d..ece03e7d8 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1219,6 +1219,7 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F int find_applet_by_name(const char *name) FAST_FUNC; void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; #endif +void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; #if defined(__linux__) void set_task_comm(const char *comm) FAST_FUNC; #else diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 542211255..67c540abb 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -905,16 +905,8 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) # endif # if NUM_APPLETS > 0 -void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) +void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) { - int argc = string_array_len(argv); - - /* - * We do not use argv[0]: do not want to repeat massaging of - * "-/sbin/halt" -> "halt", for example. - */ - applet_name = name; - /* Special case. POSIX says "test --help" * should be no different from e.g. "test --foo". * Thus for "test", we skip --help check. @@ -931,15 +923,32 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar && applet_no != APPLET_NO_false # endif ) { - if (argc == 2 && strcmp(argv[1], "--help") == 0) { + if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { /* Make "foo --help" exit with 0: */ xfunc_error_retval = 0; bb_show_usage(); } } +} + +void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) +{ + int argc; + + /* + * We do not use argv[0]: do not want to repeat massaging of + * "-/sbin/halt" -> "halt", for example. + */ + applet_name = name; + + show_usage_if_dash_dash_help(applet_no, argv); + if (ENABLE_FEATURE_SUID) check_suid(applet_no); + + argc = string_array_len(argv); xfunc_error_retval = applet_main[applet_no](argc, argv); + /* Note: applet_main() may also not return (die on a xfunc or such) */ xfunc_die(); } diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 65271e84f..a49fe8e01 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -109,8 +109,13 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) char *tmp_argv[argc+1]; memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); applet_name = tmp_argv[0]; + + /* longjmp's (instead of returning) if --help is seen */ + show_usage_if_dash_dash_help(applet_no, argv); + /* Finally we can call NOFORK applet's main() */ rc = applet_main[applet_no](argc, tmp_argv); + /* Important for shells: `which CMD` was failing */ fflush_all(); } else { -- cgit v1.2.3 From 64483324c5422ad8e3cf413929b1360ce6245e7e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 20 Feb 2021 18:09:54 +0100 Subject: udhcpc: clarify bcast/unicast sends in logs, include server ID Before: sending discover sending select for 192.168.1.173 lease of 192.168.1.173 obtained, lease time 43200 sending renew to 192.168.1.1 lease of 192.168.1.173 obtained, lease time 43200 After: broadcasting discover broadcasting select for 192.168.1.173, server 192.168.1.1 lease of 192.168.1.173 obtained from 192.168.1.1, lease time 43200 sending renew to server 192.168.1.1 lease of 192.168.1.173 obtained from 192.168.1.1, lease time 43200 function old new delta udhcpc_main 2580 2610 +30 send_select 104 130 +26 send_renew 82 99 +17 send_discover 94 89 -5 send_decline 93 88 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/2 up/down: 73/-10) Total: 63 bytes text data bss dec hex filename 1019732 559 5020 1025311 fa51f busybox_old 1019898 559 5020 1025477 fa5c5 busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 922c71ebd..f1f6720f3 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -729,7 +729,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) */ add_client_options(&packet); - bb_info_msg("sending %s", "discover"); + bb_simple_info_msg("broadcasting discover"); return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } @@ -742,6 +742,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste { struct dhcp_packet packet; struct in_addr temp_addr; + char server_str[sizeof("255.255.255.255")]; /* * RFC 2131 4.3.2 DHCPREQUEST message @@ -772,8 +773,13 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste */ add_client_options(&packet); + temp_addr.s_addr = server; + strcpy(server_str, inet_ntoa(temp_addr)); temp_addr.s_addr = requested; - bb_info_msg("sending select for %s", inet_ntoa(temp_addr)); + bb_info_msg("broadcasting select for %s, server %s", + inet_ntoa(temp_addr), + server_str + ); return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } @@ -782,7 +788,6 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) { struct dhcp_packet packet; - struct in_addr temp_addr; /* * RFC 2131 4.3.2 DHCPREQUEST message @@ -813,8 +818,14 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) */ add_client_options(&packet); - temp_addr.s_addr = server; - bb_info_msg("sending renew to %s", inet_ntoa(temp_addr)); + if (server) { + struct in_addr temp_addr; + temp_addr.s_addr = server; + bb_info_msg("sending renew to server %s", inet_ntoa(temp_addr)); + } else { + bb_simple_info_msg("broadcasting renew"); + } + return bcast_or_ucast(&packet, ciaddr, server); } @@ -843,7 +854,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); - bb_info_msg("sending %s", "decline"); + bb_simple_info_msg("broadcasting decline"); return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } #endif @@ -1720,6 +1731,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) unsigned start; uint32_t lease_seconds; struct in_addr temp_addr; + char server_str[sizeof("255.255.255.255")]; uint8_t *temp; temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); @@ -1775,9 +1787,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } #endif /* enter bound state */ + temp_addr.s_addr = server_addr; + strcpy(server_str, inet_ntoa(temp_addr)); temp_addr.s_addr = packet.yiaddr; - bb_info_msg("lease of %s obtained, lease time %u", - inet_ntoa(temp_addr), (unsigned)lease_seconds); + bb_info_msg("lease of %s obtained from %s, lease time %u", + inet_ntoa(temp_addr), server_str, (unsigned)lease_seconds); requested_ip = packet.yiaddr; start = monotonic_sec(); -- cgit v1.2.3 From 5024d862551a762f8e95d887830710cd32c03fb8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Feb 2021 08:54:08 +0100 Subject: ntpd: increase loglevel to 3 for "poll:32s sockets:0 interval:64s" message Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 1f17b08ef..8c9e59de1 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -2767,7 +2767,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) timeout++; /* (nextaction - G.cur_time) rounds down, compensating */ /* Here we may block */ - VERB2 { + VERB3 { if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) { /* We wait for at least one reply. * Poll for it, without wasting time for message. -- cgit v1.2.3 From 423c4c25d8496a6e784b4ebbbaf1a6f4ae490f9b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Feb 2021 09:05:48 +0100 Subject: ntpd: remove unused USING_INITIAL_FREQ_ESTIMATION code Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 184 +----------------------------------------------------- 1 file changed, 2 insertions(+), 182 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 8c9e59de1..62543ad2f 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -373,8 +373,7 @@ typedef struct { } peer_t; -#define USING_KERNEL_PLL_LOOP 1 -#define USING_INITIAL_FREQ_ESTIMATION 0 +#define USING_KERNEL_PLL_LOOP 1 enum { OPT_n = (1 << 0), @@ -657,104 +656,11 @@ filter_datapoints(peer_t *p) double sum, wavg; datapoint_t *fdp; -#if 0 /* Simulations have shown that use of *averaged* offset for p->filter_offset * is in fact worse than simply using last received one: with large poll intervals * (>= 2048) averaging code uses offset values which are outdated by hours, * and time/frequency correction goes totally wrong when fed essentially bogus offsets. */ - int got_newest; - double minoff, maxoff, w; - double x = x; /* for compiler */ - double oldest_off = oldest_off; - double oldest_age = oldest_age; - double newest_off = newest_off; - double newest_age = newest_age; - - fdp = p->filter_datapoint; - - minoff = maxoff = fdp[0].d_offset; - for (i = 1; i < NUM_DATAPOINTS; i++) { - if (minoff > fdp[i].d_offset) - minoff = fdp[i].d_offset; - if (maxoff < fdp[i].d_offset) - maxoff = fdp[i].d_offset; - } - - idx = p->datapoint_idx; /* most recent datapoint's index */ - /* Average offset: - * Drop two outliers and take weighted average of the rest: - * most_recent/2 + older1/4 + older2/8 ... + older5/32 + older6/32 - * we use older6/32, not older6/64 since sum of weights should be 1: - * 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + 1/32 = 1 - */ - wavg = 0; - w = 0.5; - /* n-1 - * --- dispersion(i) - * filter_dispersion = \ ------------- - * / (i+1) - * --- 2 - * i=0 - */ - got_newest = 0; - sum = 0; - for (i = 0; i < NUM_DATAPOINTS; i++) { - VERB5 { - bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", - i, - fdp[idx].d_offset, - fdp[idx].d_dispersion, dispersion(&fdp[idx]), - G.cur_time - fdp[idx].d_recv_time, - (minoff == fdp[idx].d_offset || maxoff == fdp[idx].d_offset) - ? " (outlier by offset)" : "" - ); - } - - sum += dispersion(&fdp[idx]) / (2 << i); - - if (minoff == fdp[idx].d_offset) { - minoff -= 1; /* so that we don't match it ever again */ - } else - if (maxoff == fdp[idx].d_offset) { - maxoff += 1; - } else { - oldest_off = fdp[idx].d_offset; - oldest_age = G.cur_time - fdp[idx].d_recv_time; - if (!got_newest) { - got_newest = 1; - newest_off = oldest_off; - newest_age = oldest_age; - } - x = oldest_off * w; - wavg += x; - w /= 2; - } - - idx = (idx - 1) & (NUM_DATAPOINTS - 1); - } - p->filter_dispersion = sum; - wavg += x; /* add another older6/64 to form older6/32 */ - /* Fix systematic underestimation with large poll intervals. - * Imagine that we still have a bit of uncorrected drift, - * and poll interval is big (say, 100 sec). Offsets form a progression: - * 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 - 0.7 is most recent. - * The algorithm above drops 0.0 and 0.7 as outliers, - * and then we have this estimation, ~25% off from 0.7: - * 0.1/32 + 0.2/32 + 0.3/16 + 0.4/8 + 0.5/4 + 0.6/2 = 0.503125 - */ - x = oldest_age - newest_age; - if (x != 0) { - x = newest_age / x; /* in above example, 100 / (600 - 100) */ - if (x < 1) { /* paranoia check */ - x = (newest_off - oldest_off) * x; /* 0.5 * 100/500 = 0.1 */ - wavg += x; - } - } - p->filter_offset = wavg; - -#else - fdp = p->filter_datapoint; idx = p->datapoint_idx; /* most recent datapoint's index */ @@ -777,7 +683,6 @@ filter_datapoints(peer_t *p) } wavg /= NUM_DATAPOINTS; p->filter_dispersion = sum; -#endif /* +----- -----+ ^ 1/2 * | n-1 | @@ -1572,8 +1477,6 @@ update_local_clock(peer_t *p) double abs_offset; #if !USING_KERNEL_PLL_LOOP double freq_drift; -#endif -#if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION double since_last_update; #endif double etemp, dtemp; @@ -1603,63 +1506,15 @@ update_local_clock(peer_t *p) * action is and defines how the system reacts to large time * and frequency errors. */ -#if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION - since_last_update = recv_time - G.reftime; -#endif #if !USING_KERNEL_PLL_LOOP + since_last_update = recv_time - G.reftime; freq_drift = 0; #endif -#if USING_INITIAL_FREQ_ESTIMATION - if (G.discipline_state == STATE_FREQ) { - /* Ignore updates until the stepout threshold */ - if (since_last_update < WATCH_THRESHOLD) { - VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", - WATCH_THRESHOLD - since_last_update); - return 0; /* "leave poll interval as is" */ - } -# if !USING_KERNEL_PLL_LOOP - freq_drift = (offset - G.last_update_offset) / since_last_update; -# endif - } -#endif /* There are two main regimes: when the * offset exceeds the step threshold and when it does not. */ if (abs_offset > STEP_THRESHOLD) { -#if 0 - double remains; - -// This "spike state" seems to be useless, peer selection already drops -// occassional "bad" datapoints. If we are here, there were _many_ -// large offsets. When a few first large offsets are seen, -// we end up in "no valid datapoints, no peer selected" state. -// Only when enough of them are seen (which means it's not a fluke), -// we end up here. Looks like _our_ clock is off. - switch (G.discipline_state) { - case STATE_SYNC: - /* The first outlyer: ignore it, switch to SPIK state */ - VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", - p->p_dotted, offset, - ""); - G.discipline_state = STATE_SPIK; - return -1; /* "decrease poll interval" */ - - case STATE_SPIK: - /* Ignore succeeding outlyers until either an inlyer - * is found or the stepout threshold is exceeded. - */ - remains = WATCH_THRESHOLD - since_last_update; - if (remains > 0) { - VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", - p->p_dotted, offset, - ", datapoint ignored"); - return -1; /* "decrease poll interval" */ - } - /* fall through: we need to step */ - } /* switch */ -#endif - /* Step the time and clamp down the poll interval. * * In NSET state an initial frequency correction is @@ -1694,12 +1549,6 @@ update_local_clock(peer_t *p) recv_time += offset; -#if USING_INITIAL_FREQ_ESTIMATION - if (G.discipline_state == STATE_NSET) { - set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time); - return 1; /* "ok to increase poll interval" */ - } -#endif abs_offset = offset = 0; set_new_values(STATE_SYNC, offset, recv_time); } else { /* abs_offset <= STEP_THRESHOLD */ @@ -1726,39 +1575,10 @@ update_local_clock(peer_t *p) */ exit(0); } -#if USING_INITIAL_FREQ_ESTIMATION - /* This is the first update received and the frequency - * has not been initialized. The first thing to do - * is directly measure the oscillator frequency. - */ - set_new_values(STATE_FREQ, offset, recv_time); -#else set_new_values(STATE_SYNC, offset, recv_time); -#endif VERB4 bb_simple_error_msg("transitioning to FREQ, datapoint ignored"); return 0; /* "leave poll interval as is" */ -#if 0 /* this is dead code for now */ - case STATE_FSET: - /* This is the first update and the frequency - * has been initialized. Adjust the phase, but - * don't adjust the frequency until the next update. - */ - set_new_values(STATE_SYNC, offset, recv_time); - /* freq_drift remains 0 */ - break; -#endif - -#if USING_INITIAL_FREQ_ESTIMATION - case STATE_FREQ: - /* since_last_update >= WATCH_THRESHOLD, we waited enough. - * Correct the phase and frequency and switch to SYNC state. - * freq_drift was already estimated (see code above) - */ - set_new_values(STATE_SYNC, offset, recv_time); - break; -#endif - default: #if !USING_KERNEL_PLL_LOOP /* Compute freq_drift due to PLL and FLL contributions. -- cgit v1.2.3 From 2620d387141c16bdce74dd9d91043ee3869febc4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Feb 2021 09:13:05 +0100 Subject: ntpd: without INITIAL_FREQ_ESTIMATION code, state variable is not needed too function old new delta update_local_clock 917 872 -45 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 88 +++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 62543ad2f..ede993078 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -461,12 +461,7 @@ struct globals { #define G_precision_sec 0.002 uint8_t stratum; -#define STATE_NSET 0 /* initial state, "nothing is set" */ -//#define STATE_FSET 1 /* frequency set from file */ -//#define STATE_SPIK 2 /* spike detected */ -//#define STATE_FREQ 3 /* initial frequency */ -#define STATE_SYNC 4 /* clock synchronized (normal operation) */ - uint8_t discipline_state; // doc calls it c.state + //uint8_t discipline_state; // doc calls it c.state uint8_t poll_exp; // s.poll int polladj_count; // c.count int FREQHOLD_cnt; @@ -1453,15 +1448,14 @@ select_and_cluster(void) * Local clock discipline and its helpers */ static void -set_new_values(int disc_state, double offset, double recv_time) +set_new_values(double offset, double recv_time) { /* Enter new state and set state variables. Note we use the time * of the last clock filter sample, which must be earlier than * the current time. */ - VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", - disc_state, offset, recv_time); - G.discipline_state = disc_state; + VERB4 bb_error_msg("last update offset=%f recv_time=%f", + offset, recv_time); G.last_update_offset = offset; G.last_update_recv_time = recv_time; } @@ -1550,9 +1544,16 @@ update_local_clock(peer_t *p) recv_time += offset; abs_offset = offset = 0; - set_new_values(STATE_SYNC, offset, recv_time); + set_new_values(offset, recv_time); } else { /* abs_offset <= STEP_THRESHOLD */ + if (option_mask32 & OPT_q) { + /* We were only asked to set time once. + * The clock is precise enough, no need to step. + */ + exit(0); + } + /* The ratio is calculated before jitter is updated to make * poll adjust code more sensitive to large offsets. */ @@ -1567,46 +1568,31 @@ update_local_clock(peer_t *p) if (G.discipline_jitter < G_precision_sec) G.discipline_jitter = G_precision_sec; - switch (G.discipline_state) { - case STATE_NSET: - if (option_mask32 & OPT_q) { - /* We were only asked to set time once. - * The clock is precise enough, no need to step. - */ - exit(0); - } - set_new_values(STATE_SYNC, offset, recv_time); - VERB4 bb_simple_error_msg("transitioning to FREQ, datapoint ignored"); - return 0; /* "leave poll interval as is" */ - - default: #if !USING_KERNEL_PLL_LOOP - /* Compute freq_drift due to PLL and FLL contributions. - * - * The FLL and PLL frequency gain constants - * depend on the poll interval and Allan - * intercept. The FLL is not used below one-half - * the Allan intercept. Above that the loop gain - * increases in steps to 1 / AVG. - */ - if ((1 << G.poll_exp) > ALLAN / 2) { - etemp = FLL - G.poll_exp; - if (etemp < AVG) - etemp = AVG; - freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp); - } - /* For the PLL the integration interval - * (numerator) is the minimum of the update - * interval and poll interval. This allows - * oversampling, but not undersampling. - */ - etemp = MIND(since_last_update, (1 << G.poll_exp)); - dtemp = (4 * PLL) << G.poll_exp; - freq_drift += offset * etemp / SQUARE(dtemp); -#endif - set_new_values(STATE_SYNC, offset, recv_time); - break; + /* Compute freq_drift due to PLL and FLL contributions. + * + * The FLL and PLL frequency gain constants + * depend on the poll interval and Allan + * intercept. The FLL is not used below one-half + * the Allan intercept. Above that the loop gain + * increases in steps to 1 / AVG. + */ + if ((1 << G.poll_exp) > ALLAN / 2) { + etemp = FLL - G.poll_exp; + if (etemp < AVG) + etemp = AVG; + freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp); } + /* For the PLL the integration interval + * (numerator) is the minimum of the update + * interval and poll interval. This allows + * oversampling, but not undersampling. + */ + etemp = MIND(since_last_update, (1 << G.poll_exp)); + dtemp = (4 * PLL) << G.poll_exp; + freq_drift += offset * etemp / SQUARE(dtemp); +#endif + set_new_values(offset, recv_time); if (G.stratum != p->lastpkt_stratum + 1) { G.stratum = p->lastpkt_stratum + 1; run_script("stratum", offset); @@ -1625,9 +1611,7 @@ update_local_clock(peer_t *p) G.rootdisp = p->lastpkt_rootdisp + dtemp; VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); - /* We are in STATE_SYNC now, but did not do adjtimex yet. - * (Any other state does not reach this, they all return earlier) - * By this time, freq_drift and offset are set + /* By this time, freq_drift and offset are set * to values suitable for adjtimex. */ #if !USING_KERNEL_PLL_LOOP -- cgit v1.2.3 From 855aeacfba83a776f529da7a82b749081652a486 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Feb 2021 09:47:34 +0100 Subject: ntpd: log responses to clients at log level 3 function old new delta recv_and_process_client_pkt 670 706 +36 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/networking/ntpd.c b/networking/ntpd.c index ede993078..9c15999f3 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -2153,6 +2153,12 @@ recv_and_process_client_pkt(void /*int fd*/) do_sendto(G_listen_fd, /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, &msg, size); + VERB3 { + char *addr; + addr = xmalloc_sockaddr2dotted_noport(from); + bb_error_msg("responded to query from %s", addr); + free(addr); + } bail: free(to); -- cgit v1.2.3 From a4959eef71067dd6763bf60113bdeafdcb5f2d91 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Feb 2021 16:32:07 +0100 Subject: udhcp: reuse strings text data bss dec hex filename 1019916 559 5020 1025495 fa5d7 busybox_old 1019906 559 5020 1025485 fa5cd busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 14 ++++++++------ networking/udhcp/dhcpc.c | 6 ++++-- networking/udhcp/dhcpd.c | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index fbdaa99bd..76b087b92 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -1589,8 +1589,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } if ((packet.d6_xid32 & htonl(0x00ffffff)) != xid) { - log1("xid %x (our is %x), ignoring packet", - (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)xid); + log1("xid %x (our is %x)%s", + (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)xid, + ", ignoring packet" + ); continue; } @@ -1743,7 +1745,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) free(client6_data.ia_na); client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); if (!client6_data.ia_na) { - bb_info_msg("no %s option, ignoring packet", "IA_NA"); + bb_info_msg("no %s option%s", "IA_NA", ", ignoring packet"); continue; } if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { @@ -1756,7 +1758,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) D6_OPT_IAADDR ); if (!iaaddr) { - bb_info_msg("no %s option, ignoring packet", "IAADDR"); + bb_info_msg("no %s option%s", "IAADDR", ", ignoring packet"); continue; } if (iaaddr->len < (16 + 4 + 4)) { @@ -1781,7 +1783,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) free(client6_data.ia_pd); client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD); if (!client6_data.ia_pd) { - bb_info_msg("no %s option, ignoring packet", "IA_PD"); + bb_info_msg("no %s option%s", "IA_PD", ", ignoring packet"); continue; } if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) { @@ -1794,7 +1796,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) D6_OPT_IAPREFIX ); if (!iaprefix) { - bb_info_msg("no %s option, ignoring packet", "IAPREFIX"); + bb_info_msg("no %s option%s", "IAPREFIX", ", ignoring packet"); continue; } if (iaprefix->len < (4 + 4 + 1 + 16)) { diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index f1f6720f3..bbcbd1fca 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1655,8 +1655,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } if (packet.xid != xid) { - log1("xid %x (our is %x), ignoring packet", - (unsigned)packet.xid, (unsigned)xid); + log1("xid %x (our is %x)%s", + (unsigned)packet.xid, (unsigned)xid, + ", ignoring packet" + ); continue; } diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index cd32cb437..260130507 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -1048,7 +1048,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) move_from_unaligned32(server_id_network_order, server_id_opt); if (server_id_network_order != server_data.server_nip) { /* client talks to somebody else */ - log1("server ID doesn't match%s", ", ignoring"); + log1("server ID doesn't match%s", ", ignoring packet"); continue; } } @@ -1171,7 +1171,7 @@ o DHCPREQUEST generated during REBINDING state: if (!requested_ip_opt) { requested_nip = packet.ciaddr; if (requested_nip == 0) { - log1("no requested IP and no ciaddr%s", ", ignoring"); + log1("no requested IP and no ciaddr%s", ", ignoring packet"); break; } } -- cgit v1.2.3 From 9fa7d7d97d374b091819670299f25cad87a75779 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 22 Feb 2021 15:36:07 +0100 Subject: dnsd: check that we don't read past packet function old new delta dnsd_main 1296 1304 +8 Signed-off-by: Denys Vlasenko --- networking/dnsd.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/networking/dnsd.c b/networking/dnsd.c index 0ff0290fb..a0f320c6c 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -379,7 +379,8 @@ Domain name in a message can be represented as either: */ static int process_packet(struct dns_entry *conf_data, uint32_t conf_ttl, - uint8_t *buf) + uint8_t *buf, + unsigned buflen) { struct dns_head *head; struct type_and_class *unaligned_type_class; @@ -402,9 +403,6 @@ static int process_packet(struct dns_entry *conf_data, bb_simple_error_msg("response packet, ignored"); return 0; /* don't reply */ } - /* QR = 1 "response", RCODE = 4 "Not Implemented" */ - outr_flags = htons(0x8000 | 4); - err_msg = NULL; /* start of query string */ query_string = (void *)(head + 1); @@ -416,6 +414,15 @@ static int process_packet(struct dns_entry *conf_data, /* where to append answer block */ answb = (void *)(unaligned_type_class + 1); + if (buflen < answb - buf) { + bb_simple_error_msg("packet too short"); + return 0; /* don't reply */ + } + + /* QR = 1 "response", RCODE = 4 "Not Implemented" */ + outr_flags = htons(0x8000 | 4); + err_msg = NULL; + /* OPCODE != 0 "standard query"? */ if ((head->flags & htons(0x7800)) != 0) { err_msg = "opcode != 0"; @@ -559,7 +566,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) if (OPT_verbose) bb_simple_info_msg("got UDP packet"); buf[r] = '\0'; /* paranoia */ - r = process_packet(conf_data, conf_ttl, buf); + r = process_packet(conf_data, conf_ttl, buf, r); if (r <= 0) continue; send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); -- cgit v1.2.3 From 858f8aafacf93ff4642a2f62dc0d7f0f31f95cce Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 16 Feb 2021 09:09:12 +0000 Subject: diff: code shrink function old new delta diff_main 1515 1495 -20 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-20) Total: -20 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/diff.c b/editors/diff.c index 280091756..1adc4cbc7 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -1050,7 +1050,7 @@ int diff_main(int argc UNUSED_PARAM, char **argv) /* diffreg can get non-regular files here */ print_status(gotstdin > 1 ? STATUS_SAME : diffreg(file), file); - if (dirfile) + if (ENABLE_FEATURE_CLEAN_UP && dirfile) free(file[dir]); } -- cgit v1.2.3 From 760b627e2ac6aedbf604040951280eaaf75939a8 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 18 Feb 2021 09:50:29 +0000 Subject: lineedit: support empty PATH entries in tab completion Zero-length path prefixes can be specified in PATH as a leading or trailing colon or two adjacent colons. POSIX says that the use of zero-length prefixes to refer to the current directory is a legacy feature. Nonetheless the shells in BusyBox respect this feature, as does 'which'. Tab-completion of executables using PATH should support this too. function old new delta complete_cmd_dir_file 934 931 -3 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-3) Total: -3 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 367396b91..b0adcf140 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -769,8 +769,6 @@ static unsigned path_parse(char ***p) if (!tmp) break; tmp++; - if (*tmp == '\0') - break; /* : */ npth++; } @@ -782,8 +780,6 @@ static unsigned path_parse(char ***p) if (!tmp) break; *tmp++ = '\0'; /* ':' -> '\0' */ - if (*tmp == '\0') - break; /* : */ res[npth++] = tmp; } /* special case: "match subdirectories of the current directory" */ @@ -854,6 +850,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) struct dirent *next; struct stat st; char *found; + const char *lpath; if (paths[i] == NULL) { /* path_parse()'s last component? */ /* in PATH completion, current dir's subdir names @@ -863,7 +860,8 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) paths[i] = (char *)"."; } - dir = opendir(paths[i]); + lpath = *paths[i] ? paths[i] : "."; + dir = opendir(lpath); if (!dir) continue; /* don't print an error */ @@ -878,7 +876,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) if (strncmp(basecmd, name_found, baselen) != 0) continue; /* no */ - found = concat_path_file(paths[i], name_found); + found = concat_path_file(lpath, name_found); /* NB: stat() first so that we see is it a directory; * but if that fails, use lstat() so that * we still match dangling links */ -- cgit v1.2.3 From e880c9c100028e6b0e805d4637139c67aea83748 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 22 Jan 2021 08:35:55 +0100 Subject: echo: do not assume that free() leaves errno unmodified musl libc's mallocng free() may modify errno if kernel does not support MADV_FREE which causes echo to echo with error when it shouldn't. Future versions of POSIX[1] will require that free() leaves errno unmodified but til then, do not rely free() implementation. Should fix downstream issues: https://github.com/alpinelinux/docker-alpine/issues/134 https://gitlab.alpinelinux.org/alpine/aports/-/issues/12311 Signed-off-by: Natanael Copa Signed-off-by: Denys Vlasenko --- coreutils/echo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/coreutils/echo.c b/coreutils/echo.c index b3828894c..61ba060ec 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c @@ -97,6 +97,7 @@ int echo_main(int argc UNUSED_PARAM, char **argv) #else char nflag = 1; char eflag = 0; + int err; while ((arg = *++argv) != NULL) { char n, e; @@ -185,13 +186,12 @@ int echo_main(int argc UNUSED_PARAM, char **argv) do_write: /* Careful to error out on partial writes too (think ENOSPC!) */ errno = 0; - /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer); - free(buffer); - if (/*WRONG:r < 0*/ errno) { + err = full_write(STDOUT_FILENO, buffer, out - buffer) != out - buffer; + if (err) { bb_simple_perror_msg(bb_msg_write_error); - return 1; } - return 0; + free(buffer); + return err; } /* -- cgit v1.2.3 From 1f9ed02caffb269e5fc6fbdf19fc9ba05a79e628 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 23 Feb 2021 23:09:49 +0100 Subject: trylink: do not drop libs from CONFIG_EXTRA_LDLIBS Signed-off-by: Denys Vlasenko --- Makefile | 1 + Makefile.flags | 5 ----- scripts/trylink | 17 ++++++++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 17f55dce2..ea182325d 100644 --- a/Makefile +++ b/Makefile @@ -612,6 +612,7 @@ quiet_cmd_busybox__ ?= LINK $@ "$(core-y)" \ "$(libs-y)" \ "$(LDLIBS)" \ + "$(CONFIG_EXTRA_LDLIBS)" \ && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h # Generate System.map diff --git a/Makefile.flags b/Makefile.flags index 7a445c3b5..3b02bfaac 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -209,11 +209,6 @@ LDFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_LDFLAGS))) #")) endif -ifneq ($(CONFIG_EXTRA_LDLIBS),) -LDLIBS += $(strip $(subst ",,$(CONFIG_EXTRA_LDLIBS))) -#")) -endif - # Busybox is a stack-fatty so make sure we increase default size # TODO: use "make stksizes" to find & fix big stack users # (we stole scripts/checkstack.pl from the kernel... thanks guys!) diff --git a/scripts/trylink b/scripts/trylink index 6b74f092d..2255deee7 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -1,5 +1,6 @@ #!/bin/sh +#debug=true debug=false # Linker flags used: @@ -77,7 +78,13 @@ CFLAGS="$3" LDFLAGS="$4" O_FILES="$5" A_FILES="$6" +# We try to drop libraries from LDLIBS if build works without them, +# but ones from CONFIG_EXTRA_LDLIBS are always linked in. +# (For example, musl has stub utmp implementation, and if you link with +# a real utmp library in LDLIBS, dropping it "works" but resulting binary +# does not work properly). LDLIBS="$7" +CONFIG_EXTRA_LDLIBS="$8" # The --sort-section option is not supported by older versions of ld SORT_SECTION="-Wl,--sort-section,alignment" @@ -125,8 +132,8 @@ LDLIBS=`echo "$LDLIBS" | xargs -n1 | sort | uniq | xargs` # First link with all libs. If it fails, bail out echo "Trying libraries: $LDLIBS" # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" -l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` -test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" +l_list=`echo " $LDLIBS $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` +test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" try $CC $CFLAGS $LDFLAGS \ -o $EXE \ $SORT_COMMON \ @@ -151,7 +158,7 @@ while test "$LDLIBS"; do for one in $LDLIBS; do without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs` # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" - l_list=`echo " $without_one " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` + l_list=`echo " $without_one $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" $debug && echo "Trying -l options: '$l_list'" try $CC $CFLAGS $LDFLAGS \ @@ -179,8 +186,8 @@ done # Make the binary with final, minimal list of libs echo "Final link with: ${LDLIBS:-}" -l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` -test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" +l_list=`echo " $LDLIBS $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` +test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" # --verbose gives us gobs of info to stdout (e.g. linker script used) if ! test -f busybox_ldscript; then try $CC $CFLAGS $LDFLAGS \ -- cgit v1.2.3 From 3d88cc1d371a4a5ae8e1521a1e915479bca52959 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 13:26:48 +0100 Subject: dc: correct --help text before: Tiny RPN calculator. Operations: +, -, *, /, %, ~, ^, |, p - print top of the stack without popping f - print entire stack k - pop the value and set the precision i - pop the value and set input radix o - pop the value and set output radix After: Tiny RPN calculator. Operations: Arithmetic: + - * / % ^ ~ - divide with remainder | - modular exponentiation v - square root p - print top of the stack without popping f - print entire stack k - pop the value and set precision i - pop the value and set input radix o - pop the value and set output radix function old new delta packed_usage 33519 33565 +46 Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/miscutils/bc.c b/miscutils/bc.c index 02a61ac49..84bbe7b14 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -138,11 +138,53 @@ //usage: //usage:#define dc_full_usage "\n" //usage: "\nTiny RPN calculator. Operations:" -//usage: "\n+, -, *, /, %, ~, ^," IF_FEATURE_DC_BIG(" |,") +//usage: "\nArithmetic: + - * / % ^" +//usage: IF_FEATURE_DC_BIG( +//usage: "\n~ - divide with remainder" +//usage: "\n| - modular exponentiation" +//usage: "\nv - square root" +//////// "\n_NNN - push neagtive number -NNN +//////// "\n[string] - push string +//////// "\nR - DC_LEX_POP pop and discard +//////// "\nc - DC_LEX_CLEAR_STACK clear stack +//////// "\nd - DC_LEX_DUPLICATE pop, push, push +//////// "\nr - DC_LEX_SWAP pop 1, pop 2, push 1, push 2 +//////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' +//////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push +//////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push +//////// "\nSr - DC_LEX_STORE_PUSH pop, push to register 'r' +//////// "\nlr - DC_LEX_LOAD read register 'r', push +//////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' +//////// "\n? - DC_LEX_READ read line and execute +//////// "\nx - DC_LEX_EXECUTE pop string and execute +//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was less +//////// "\n=r - XC_LEX_OP_REL_EQ pop, pop, execute register 'r' if equal +//////// "\n!r !=r - negated forms +//////// "\ne - DC_LEX_ELSE >tef: "if greater execute 't' else execute 'f'" +//////// "\nQ - DC_LEX_NQUIT pop, "break N" from macro invocations +//////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) +//////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits +//////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) +//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st string char +//////// "\n( - DC_LEX_LPAREN ? +//////// "\n{ - DC_LEX_LBRACE ? +//////// "\n_ - XC_LEX_NEG (not a command - starts negative number) +//////// "\nG - DC_LEX_EQ_NO_REG (? GNU dc has no such cmd) +//////// "\nN - DC_LEX_OP_BOOL_NOT (? GNU dc has no such cmd) +//////// "\nn - DC_LEX_PRINT_POP pop, print without newline +//////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes +//usage: ) //usage: "\np - print top of the stack without popping" //usage: "\nf - print entire stack" -//usage: "\nk - pop the value and set the precision" +//////// "\nz - DC_LEX_STACK_LEVEL push stack depth +//////// "\nK - DC_LEX_SCALE push precision +//////// "\nI - DC_LEX_IBASE push input radix +//////// "\nO - DC_LEX_OBASE push output radix +//usage: IF_FEATURE_DC_BIG( +//usage: "\nk - pop the value and set precision" //usage: "\ni - pop the value and set input radix" +//usage: ) //usage: "\no - pop the value and set output radix" //usage: "\nExamples: dc -e'2 2 + p' -> 4, dc -e'8 8 * 2 2 + / p' -> 16" //usage: -- cgit v1.2.3 From ace81cd46ce53e60fe702cc1ac857989207e7ac4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 14:05:28 +0100 Subject: bc/dc: fix length(0) and length(0.000nnn) result function old new delta zxc_vm_process 6464 6498 +34 Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 17 +++++++++++++---- testsuite/bc.tests | 5 +++++ testsuite/dc.tests | 5 +++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/miscutils/bc.c b/miscutils/bc.c index 84bbe7b14..91564099e 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -6259,13 +6259,20 @@ static unsigned long xc_program_len(BcNum *n) { size_t len = n->len; - if (n->rdx != len) return len; + if (n->rdx != len) + // length(100): rdx 0 len 3, return 3 + // length(0.01-0.01): rdx 2 len 0, return 2 + // dc: 0.01 0.01 - Zp: rdx 2 len 0, return 1 + return len != 0 ? len : (IS_BC ? n->rdx : 1); + + // length(0): return 1 + // length(0.000nnn): count nnn for (;;) { if (len == 0) break; len--; if (n->num[len] != 0) break; } - return len; + return len + 1; } static BC_STATUS zxc_program_builtin(char inst) @@ -6293,12 +6300,12 @@ static BC_STATUS zxc_program_builtin(char inst) if (inst == XC_INST_SQRT) s = zbc_num_sqrt(num, &res.d.n, G.prog.scale); #if ENABLE_BC - else if (len != 0 && opnd->t == XC_RESULT_ARRAY) { + else if (len && opnd->t == XC_RESULT_ARRAY) { bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); } #endif #if ENABLE_DC - else if (len != 0 && !BC_PROG_NUM(opnd, num)) { + else if (len && !BC_PROG_NUM(opnd, num)) { char **str; size_t idx = opnd->t == XC_RESULT_STR ? opnd->d.id.idx : num->rdx; @@ -6307,6 +6314,8 @@ static BC_STATUS zxc_program_builtin(char inst) } #endif else { +//TODO: length(.00) and scale(.00) should return 2, they return 1 and 0 now +//(don't forget to check that dc Z and X commands do not break) bc_num_ulong2num(&res.d.n, len ? xc_program_len(num) : xc_program_scale(num)); } diff --git a/testsuite/bc.tests b/testsuite/bc.tests index 179d5d2a2..1c748727a 100755 --- a/testsuite/bc.tests +++ b/testsuite/bc.tests @@ -182,6 +182,11 @@ testing "bc print 1,2,3" \ "123" \ "" "print 1,2,3" +testing "bc length" \ + "bc" \ + "1\n3\n1\n3\n3\n" \ + "" "length(0); length(100); length(0.01); length(0.00120); length(0.012-0.012);" + testing "bc { print 1 }" \ "bc" \ "1" \ diff --git a/testsuite/dc.tests b/testsuite/dc.tests index 361bc8459..ad0099354 100755 --- a/testsuite/dc.tests +++ b/testsuite/dc.tests @@ -114,6 +114,11 @@ testing "dc newline can be a register" \ "2\n9\n" \ "" "[2p]s\n[3p]l\nx\n9p" +testing "dc Z (length) for numbers" \ + "dc" \ + "1\n1\n3\n1\n3\n1\n" \ + "" "0Zp\n0.000Zp\n100Zp\n0.01Zp\n0.00120Zp\n0.0012 0.0012 - Zp\n" + for f in dc_*.dc; do r="`basename "$f" .dc`_results.txt" test -f "$r" || continue -- cgit v1.2.3 From 1a37aa7a88722f49928f6cd7851476aa4525462d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 14:48:04 +0100 Subject: dc: document what non-GNU commands do Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/miscutils/bc.c b/miscutils/bc.c index 91564099e..cc48ed3fe 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -166,12 +166,12 @@ //////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) //////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits //////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) -//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st string char -//////// "\n( - DC_LEX_LPAREN ? -//////// "\n{ - DC_LEX_LBRACE ? +//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st char of string +//////// "\n( - DC_LEX_LPAREN (not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 +//////// "\n{ - DC_LEX_LBRACE (not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 +//////// "\nG - DC_LEX_EQ_NO_REG (not in GNU) pop, pop, if equal push 1 else push 0 +//////// "\nN - DC_LEX_OP_BOOL_NOT (not in GNU) pop, if 0 push 1 else push 0 //////// "\n_ - XC_LEX_NEG (not a command - starts negative number) -//////// "\nG - DC_LEX_EQ_NO_REG (? GNU dc has no such cmd) -//////// "\nN - DC_LEX_OP_BOOL_NOT (? GNU dc has no such cmd) //////// "\nn - DC_LEX_PRINT_POP pop, print without newline //////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes //usage: ) -- cgit v1.2.3 From 9037757c5fde77d74e24e100efd70420a51c5d95 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 17:11:55 +0100 Subject: dc: more docs in --help Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/miscutils/bc.c b/miscutils/bc.c index cc48ed3fe..934a1f8ba 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -143,12 +143,13 @@ //usage: "\n~ - divide with remainder" //usage: "\n| - modular exponentiation" //usage: "\nv - square root" -//////// "\n_NNN - push neagtive number -NNN -//////// "\n[string] - push string +//////// "\nA-F - digits 10..15 +//////// "\n_NNN - push negative number -NNN +//////// "\n[string] - push string (in FreeBSD, \[, \] and \\ are escapes, not implemented here and in GNU) //////// "\nR - DC_LEX_POP pop and discard //////// "\nc - DC_LEX_CLEAR_STACK clear stack -//////// "\nd - DC_LEX_DUPLICATE pop, push, push -//////// "\nr - DC_LEX_SWAP pop 1, pop 2, push 1, push 2 +//////// "\nd - DC_LEX_DUPLICATE duplicate top-of-stack +//////// "\nr - DC_LEX_SWAP swap top-of-stack //////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' //////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push //////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push @@ -157,21 +158,21 @@ //////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' //////// "\n? - DC_LEX_READ read line and execute //////// "\nx - DC_LEX_EXECUTE pop string and execute -//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was less +//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was greater //////// "\n=r - XC_LEX_OP_REL_EQ pop, pop, execute register 'r' if equal -//////// "\n!r !=r - negated forms -//////// "\ne - DC_LEX_ELSE >tef: "if greater execute 't' else execute 'f'" +//////// "\n !r !=r - negated forms +//////// "\n >tef - "if greater execute register 't' else execute 'f'" //////// "\nQ - DC_LEX_NQUIT pop, "break N" from macro invocations //////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) //////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits //////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) //////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st char of string -//////// "\n( - DC_LEX_LPAREN (not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 -//////// "\n{ - DC_LEX_LBRACE (not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 -//////// "\nG - DC_LEX_EQ_NO_REG (not in GNU) pop, pop, if equal push 1 else push 0 -//////// "\nN - DC_LEX_OP_BOOL_NOT (not in GNU) pop, if 0 push 1 else push 0 -//////// "\n_ - XC_LEX_NEG (not a command - starts negative number) +//////// "\n( - DC_LEX_LPAREN (FreeBSD, not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 +//////// "\n{ - DC_LEX_LBRACE (FreeBSD, not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 +//////// "\nG - DC_LEX_EQ_NO_REG (FreeBSD, not in GNU) pop, pop, if equal push 1 else push 0 +//////// "\nN - DC_LEX_OP_BOOL_NOT (FreeBSD, not in GNU) pop, if 0 push 1 else push 0 +//////// FreeBSD also has J and M commands, used internally by bc //////// "\nn - DC_LEX_PRINT_POP pop, print without newline //////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes //usage: ) -- cgit v1.2.3 From 9b6bcfda0e11c0e73a966a77110f6c68425cff34 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 21:20:18 +0100 Subject: bc: typo fix in comment Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miscutils/bc.c b/miscutils/bc.c index 934a1f8ba..553d0f472 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -152,7 +152,7 @@ //////// "\nr - DC_LEX_SWAP swap top-of-stack //////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' //////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push -//////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push +//////// "\nLr - DC_LEX_LOAD_POP pop register 'r', push //////// "\nSr - DC_LEX_STORE_PUSH pop, push to register 'r' //////// "\nlr - DC_LEX_LOAD read register 'r', push //////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' -- cgit v1.2.3 From 63d9da322f438a98bb654cc4976874fa89f1fa62 Mon Sep 17 00:00:00 2001 From: Alison Winters Date: Sat, 27 Feb 2021 15:18:45 -0800 Subject: vi: restore 0 offset after :set noXXX command Fixes bug where commands after the first noXXX command are ignored. e.g. :set noic tabstop=4 While at it, stop recognizing "notabstop=NNN". function old new delta colon 2990 2965 -25 Signed-off-by: Alison Winters Signed-off-by: Denys Vlasenko --- editors/vi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index 458ca6293..e77c348fb 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2709,7 +2709,6 @@ static void colon(char *buf) # if ENABLE_FEATURE_VI_SETOPTS char *argp; # endif - i = 0; // offset into args // only blank is regarded as args delimiter. What about tab '\t'? if (!args[0] || strcasecmp(args, "all") == 0) { // print out values of all options @@ -2732,15 +2731,16 @@ static void colon(char *buf) # if ENABLE_FEATURE_VI_SETOPTS argp = args; while (*argp) { - if (strncmp(argp, "no", 2) == 0) - i = 2; // ":set noautoindent" + i = 0; + if (argp[0] == 'n' && argp[1] == 'o') // "noXXX" + i = 2; setops(argp, "autoindent ", i, "ai", VI_AUTOINDENT); setops(argp, "flash " , i, "fl", VI_ERR_METHOD); setops(argp, "ignorecase ", i, "ic", VI_IGNORECASE); setops(argp, "showmatch " , i, "sm", VI_SHOWMATCH ); - if (strncmp(argp + i, "tabstop=", 8) == 0) { + if (strncmp(argp, "tabstop=", 8) == 0) { int t = 0; - sscanf(argp + i+8, "%u", &t); + sscanf(argp + 8, "%u", &t); if (t > 0 && t <= MAX_TABSTOP) tabstop = t; } -- cgit v1.2.3 From 70ee23399cb2c77dec0b6ad3b6030f7cf3105b8f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 1 Mar 2021 14:41:39 +0100 Subject: vi: code shrink function old new delta setops 85 73 -12 colon 2965 2915 -50 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-62) Total: -62 bytes Signed-off-by: Denys Vlasenko --- editors/vi.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index e77c348fb..abc0aeae8 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2258,7 +2258,7 @@ static char *get_one_address(char *p, int *addr) // get colon addr, if present q = begin_line(dot); *addr = count_lines(text, q); } -#if ENABLE_FEATURE_VI_YANKMARK +# if ENABLE_FEATURE_VI_YANKMARK else if (*p == '\'') { // is this a mark addr p++; c = tolower(*p); @@ -2272,8 +2272,8 @@ static char *get_one_address(char *p, int *addr) // get colon addr, if present } } } -#endif -#if ENABLE_FEATURE_VI_SEARCH +# endif +# if ENABLE_FEATURE_VI_SEARCH else if (*p == '/') { // a search pattern q = strchrnul(p + 1, '/'); if (p + 1 != q) { @@ -2290,7 +2290,7 @@ static char *get_one_address(char *p, int *addr) // get colon addr, if present *addr = count_lines(text, q); } } -#endif +# endif else if (*p == '$') { // the last line in file p++; q = begin_line(end - 1); @@ -2333,16 +2333,13 @@ static char *get_address(char *p, int *b, int *e) // get two colon addrs, if pre return p; } -#if ENABLE_FEATURE_VI_SET && ENABLE_FEATURE_VI_SETOPTS -static void setops(const char *args, const char *opname, int flg_no, - const char *short_opname, int opt) +# if ENABLE_FEATURE_VI_SET && ENABLE_FEATURE_VI_SETOPTS +static void setops(const char *args, const char *nm_longname, int flg_no, int opt) { const char *a = args + flg_no; - int l = strlen(opname) - 1; // opname have + ' ' - // maybe strncmp? we had tons of erroneous strncasecmp's... - if (strncasecmp(a, opname, l) == 0 - || strncasecmp(a, short_opname, 2) == 0 + if (strcmp(a, nm_longname) == 0 + || strcmp(a, nm_longname + 3) == 0 ) { if (flg_no) vi_setops &= ~opt; @@ -2350,7 +2347,7 @@ static void setops(const char *args, const char *opname, int flg_no, vi_setops |= opt; } } -#endif +# endif #endif /* FEATURE_VI_COLON */ @@ -2734,13 +2731,12 @@ static void colon(char *buf) i = 0; if (argp[0] == 'n' && argp[1] == 'o') // "noXXX" i = 2; - setops(argp, "autoindent ", i, "ai", VI_AUTOINDENT); - setops(argp, "flash " , i, "fl", VI_ERR_METHOD); - setops(argp, "ignorecase ", i, "ic", VI_IGNORECASE); - setops(argp, "showmatch " , i, "sm", VI_SHOWMATCH ); + setops(argp, "ai""\0""autoindent", i, VI_AUTOINDENT); + setops(argp, "fl""\0""flash" , i, VI_ERR_METHOD); + setops(argp, "ic""\0""ignorecase", i, VI_IGNORECASE); + setops(argp, "sm""\0""showmatch" , i, VI_SHOWMATCH ); if (strncmp(argp, "tabstop=", 8) == 0) { - int t = 0; - sscanf(argp + 8, "%u", &t); + int t = bb_strtou(argp + 8, NULL, 10); if (t > 0 && t <= MAX_TABSTOP) tabstop = t; } -- cgit v1.2.3 From 2d6c175d9b8b0c8eedda2f9bcf1b96a8117ab441 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 2 Mar 2021 12:07:14 +0100 Subject: ntpd: decrease INITIAL_SAMPLES from 4 to 3 This reduces initial traffic to NTP servers when a lot of devices boot at once. Log inspection tells me we agressively burst-poll servers about 5 times at startup, even though we usually already update clock after second replies. INITIAL_SAMPLES can probably be even lower, e.g. 2, but let's be conservative when changing this stuff. Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 9c15999f3..caf5cc299 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -169,7 +169,7 @@ * datapoints after the step. */ -#define INITIAL_SAMPLES 4 /* how many samples do we want for init */ +#define INITIAL_SAMPLES 3 /* how many samples do we want for init */ #define MIN_FREQHOLD 10 /* adjust offset, but not freq in this many first adjustments */ #define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this factor */ @@ -223,7 +223,16 @@ #define MIN_SELECTED 1 /* minimum intersection survivors */ #define MIN_CLUSTERED 3 /* minimum cluster survivors */ -#define MAXDRIFT 0.000500 /* frequency drift we can correct (500 PPM) */ +/* Correct frequency ourself (0) or let kernel do it (1)? */ +#define USING_KERNEL_PLL_LOOP 1 +// /* frequency drift we can correct (500 PPM) */ +// #define MAXDRIFT 0.000500 +// /* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ +// #define ALLAN 512 +// /* PLL loop gain */ +// #define PLL 65536 +// /* FLL loop gain [why it depends on MAXPOLL??] */ +// #define FLL (MAXPOLL + 1) /* Poll-adjust threshold. * When we see that offset is small enough compared to discipline jitter, @@ -239,12 +248,6 @@ */ #define POLLADJ_GATE 4 #define TIMECONST_HACK_GATE 2 -/* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ -#define ALLAN 512 -/* PLL loop gain */ -#define PLL 65536 -/* FLL loop gain [why it depends on MAXPOLL??] */ -#define FLL (MAXPOLL + 1) /* Parameter averaging constant */ #define AVG 4 @@ -372,9 +375,6 @@ typedef struct { char p_hostname[1]; } peer_t; - -#define USING_KERNEL_PLL_LOOP 1 - enum { OPT_n = (1 << 0), OPT_q = (1 << 1), @@ -453,7 +453,7 @@ struct globals { */ #define G_precision_exp -9 /* - * G_precision_exp is used only for construction outgoing packets. + * G_precision_exp is used only for constructing outgoing packets. * It's ok to set G_precision_sec to a slightly different value * (One which is "nicer looking" in logs). * Exact value would be (1.0 / (1 << (- G_precision_exp))): @@ -484,7 +484,6 @@ struct globals { }; #define G (*ptr_to_globals) - #define VERB1 if (MAX_VERBOSE && G.verbose) #define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2) #define VERB3 if (MAX_VERBOSE >= 3 && G.verbose >= 3) @@ -989,7 +988,6 @@ send_query_to_peer(peer_t *p) set_next(p, RESPONSE_INTERVAL); } - /* Note that there is no provision to prevent several run_scripts * to be started in quick succession. In fact, it happens rather often * if initial syncronization results in a step. @@ -1767,7 +1765,6 @@ update_local_clock(peer_t *p) return 1; /* "ok to increase poll interval" */ } - /* * We've got a new reply packet from a peer, process it * (helpers first) -- cgit v1.2.3 From 2d48d9b1cca7745a514f8cf770308ceb48edb195 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 2 Mar 2021 19:54:09 +0100 Subject: ntpd: tweak comments Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index caf5cc299..0f350fa6f 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -127,24 +127,15 @@ */ #define MAX_VERBOSE 3 - /* High-level description of the algorithm: * * We start running with very small poll_exp, BURSTPOLL, * in order to quickly accumulate INITIAL_SAMPLES datapoints * for each peer. Then, time is stepped if the offset is larger - * than STEP_THRESHOLD, otherwise it isn't; anyway, we enlarge - * poll_exp to MINPOLL and enter frequency measurement step: - * we collect new datapoints but ignore them for WATCH_THRESHOLD - * seconds. After WATCH_THRESHOLD seconds we look at accumulated - * offset and estimate frequency drift. - * - * (frequency measurement step seems to not be strictly needed, - * it is conditionally disabled with USING_INITIAL_FREQ_ESTIMATION - * define set to 0) + * than STEP_THRESHOLD, otherwise it isn't stepped. * - * After this, we enter "steady state": we collect a datapoint, - * we select the best peer, if this datapoint is not a new one + * Then poll_exp is set to MINPOLL, and we enter "steady state": we collect + * a datapoint, we select the best peer, if this datapoint is not a new one * (IOW: if this datapoint isn't for selected peer), sleep * and collect another one; otherwise, use its offset to update * frequency drift, if offset is somewhat large, reduce poll_exp, @@ -189,13 +180,10 @@ // ^^^^ used to be 0.125. // Since Linux 2.6.26 (circa 2006), kernel accepts (-0.5s, +0.5s) range -/* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ -//UNUSED: #define WATCH_THRESHOLD 128 -/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ -//UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ -/* - * If we got |offset| > BIGOFF from a peer, cap next query interval +// #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ + +/* If we got |offset| > BIGOFF from a peer, cap next query interval * for this peer by this many seconds: */ #define BIGOFF STEP_THRESHOLD @@ -204,18 +192,16 @@ #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ #define BURSTPOLL 0 /* initial poll */ #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ -/* - * If offset > discipline_jitter * POLLADJ_GATE, and poll interval is > 2^BIGPOLL, +/* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is > 2^BIGPOLL, * then it is decreased _at once_. (If <= 2^BIGPOLL, it will be decreased _eventually_). */ #define BIGPOLL 9 /* 2^9 sec ~= 8.5 min */ #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ -/* - * Actively lower poll when we see such big offsets. +/* Actively lower poll when we see such big offsets. * With SLEW_THRESHOLD = 0.125, it means we try to sync more aggressively * if offset increases over ~0.04 sec */ -//#define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) +// #define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) #define MINDISP 0.01 /* minimum dispersion (sec) */ #define MAXDISP 16 /* maximum dispersion (sec) */ #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ -- cgit v1.2.3 From 307cd26e9893ed0cf6ee88e7fca2d61d3da0e139 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 9 Mar 2021 01:12:18 +0100 Subject: start-stop-daemon: explain -x + -a test Signed-off-by: Denys Vlasenko --- testsuite/start-stop-daemon.tests | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testsuite/start-stop-daemon.tests b/testsuite/start-stop-daemon.tests index 2ddb7fefb..0757b1288 100755 --- a/testsuite/start-stop-daemon.tests +++ b/testsuite/start-stop-daemon.tests @@ -21,8 +21,13 @@ testing "start-stop-daemon without -x and -a" \ "1\n" \ "" "" +# This runs /bin/false with argv[0..2] of { "qwerty", "false", NULL }. +# # Unfortunately, this does not actually check argv[0] correctness, # but at least it checks that pathname to exec() is correct +# +# NB: this fails if /bin/false is a busybox symlink: +# busybox looks at argv[0] and says "qwerty: applet not found" testing "start-stop-daemon with both -x and -a" \ 'start-stop-daemon -S -x /bin/false -a qwerty false 2>&1; echo $?' \ "1\n" \ -- cgit v1.2.3