--- ./attic/backwards.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./attic/backwards.c 2019-11-23 17:54:09.000000000 -0800 @@ -7,6 +7,8 @@ #include <stdlib.h> #include <time.h> +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define UNUSED_ARG(arg) ((void)(arg)) static void ts_print(struct timespec *ts0, struct timespec *ts1); --- ./attic/clocks.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./attic/clocks.c 2019-11-23 17:54:09.000000000 -0800 @@ -5,6 +5,8 @@ #include <stdio.h> #include <time.h> +#include "ntp_machine.h" /* For clock_gettime fallback */ + struct table { const int type; const char* name; --- ./attic/digest-timing.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./attic/digest-timing.c 2019-11-23 17:54:09.000000000 -0800 @@ -34,6 +34,8 @@ #include <openssl/rand.h> #include <openssl/objects.h> +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define UNUSED_ARG(arg) ((void)(arg)) #ifndef EVP_MD_CTX_reset --- ./include/ntp_machine.h.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./include/ntp_machine.h 2019-11-23 17:54:09.000000000 -0800 @@ -13,14 +13,145 @@ #ifndef CLOCK_REALTIME /* - * Pacify platforms that don't have a real clock_gettime(2), - * notably Mac OS X. + * Handle platforms that don't have a real clock_gettime(2), + * notably some versions of Mac OS X. */ -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 + +#include <errno.h> + typedef int clockid_t; -int clock_gettime(clockid_t clock_id, struct timespec *tp); -#endif + +#define CLOCK_REALTIME 0 + +#ifdef __APPLE__ + +#define CLOCK_MONOTONIC 1 +#define CLOCK_MONOTONIC_RAW 2 + +#include <mach/clock.h> +#include <mach/mach.h> +#include <mach/mach_time.h> + +#endif /* __APPLE__ */ + +static inline int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + { + /* + * On OSX, it's tempting to use clock_get_time() for its apparent + * nanosecond resolution, but it really only has microsecond + * resolution, and is substantially slower than gettimeofday(). + */ + struct timeval tv; + + if (gettimeofday(&tv, NULL)) + return -1; + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; + return 0; + } + +#ifdef __APPLE__ + case CLOCK_MONOTONIC: + { + mach_timespec_t mts; + static clock_serv_t sclock = 0; + + /* + * Obtain clock port on first call, then reuse it. + * Rely on exit cleanup to free it. + */ + if (!sclock) { + mach_port_t mach_host = mach_host_self(); + host_get_clock_service(mach_host, + SYSTEM_CLOCK, &sclock); + mach_port_deallocate(mach_task_self(), mach_host); + } + clock_get_time(sclock, &mts); + tp->tv_sec = mts.tv_sec; + tp->tv_nsec = mts.tv_nsec; + return 0; + } + + case CLOCK_MONOTONIC_RAW: + { + static mach_timebase_info_data_t sTimebaseInfo = {0, 0}; + unsigned long long nanos; + + /* Obtain scale factors on first call, then reuse them. */ + if ( sTimebaseInfo.denom == 0 ) { + (void) mach_timebase_info(&sTimebaseInfo); + } + nanos = mach_absolute_time() + * sTimebaseInfo.numer / sTimebaseInfo.denom; + tp->tv_sec = nanos / 1000000000U; + tp->tv_nsec = nanos - tp->tv_sec * 1000000000U; + return 0; + } +#endif /* __APPLE__ */ + + default: + errno = EINVAL; + return -1; + } +} + +static inline int clock_getres(clockid_t clk_id, struct timespec *res) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + res->tv_sec = 0; + res->tv_nsec = 1000; + return 0; + +#ifdef __APPLE__ + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_RAW: + res->tv_sec = 0; + res->tv_nsec = 1; + return 0; +#endif /* __APPLE__ */ + + default: + errno = EINVAL; + return -1; + } +} + +/* + * Prototype for settimeofday() may suppressed by feature-test flags. + * Provide it here just in case, and get an error if it mismatches. + * Similarly, "struct timezone" definition may be suppressed, but the + * incomplete definition provided here is adequate given that the + * timezone argument is unused. + */ +struct timezone; +int settimeofday(const struct timeval *, const struct timezone *); + +static inline int clock_settime(clockid_t clk_id, const struct timespec *tp) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + { + struct timeval tv; + + tv.tv_sec = tp->tv_sec; + tv.tv_usec = (tp->tv_nsec + 500) / 1000; + return settimeofday(&tv, NULL); + } + + default: + errno = EINVAL; + return -1; + } +} + +#endif /* !CLOCK_REALTIME */ int ntp_set_tod (struct timespec *tvs); --- ./include/ntp_stdlib.h.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./include/ntp_stdlib.h 2019-11-23 17:54:09.000000000 -0800 @@ -95,7 +95,9 @@ extern const char * eventstr (int); extern const char * ceventstr (int); extern const char * res_match_flags(unsigned short); extern const char * res_access_flags(unsigned short); +#ifdef HAVE_KERNEL_PLL extern const char * k_st_flags (uint32_t); +#endif extern char * statustoa (int, int); extern const char * socktoa (const sockaddr_u *); extern const char * socktoa_r (const sockaddr_u *sock, char *buf, size_t buflen); --- ./include/ntp_syscall.h.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./include/ntp_syscall.h 2019-11-23 17:54:09.000000000 -0800 @@ -9,9 +9,11 @@ #ifndef GUARD_NTP_SYSCALL_H #define GUARD_NTP_SYSCALL_H +#ifdef HAVE_SYS_TIMEX_H # include <sys/time.h> /* prerequisite on NetBSD */ # include <sys/timex.h> extern int ntp_adjtime_ns(struct timex *); +#endif /* * The units of the maxerror and esterror fields vary by platform. If --- ./libntp/clockwork.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./libntp/clockwork.c 2019-11-23 17:54:09.000000000 -0800 @@ -5,8 +5,10 @@ #include "config.h" #include <unistd.h> -#include <sys/time.h> /* prerequisite on NetBSD */ -#include <sys/timex.h> +#ifdef HAVE_SYS_TIMEX_H +# include <sys/time.h> /* prerequisite on NetBSD */ +# include <sys/timex.h> +#endif #include "ntp.h" #include "ntp_machine.h" --- ./libntp/statestr.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./libntp/statestr.c 2019-11-23 17:54:09.000000000 -0800 @@ -12,7 +12,9 @@ #include "lib_strbuf.h" #include "ntp_refclock.h" #include "ntp_control.h" +#ifdef HAVE_KERNEL_PLL # include "ntp_syscall.h" +#endif /* @@ -186,23 +188,50 @@ static const struct codestring res_acces /* not used with getcode(), no terminating entry needed */ }; +#ifdef HAVE_KERNEL_PLL /* * kernel discipline status bits */ static const struct codestring k_st_bits[] = { +# ifdef STA_PLL { STA_PLL, "pll" }, +# endif +# ifdef STA_PPSFREQ { STA_PPSFREQ, "ppsfreq" }, +# endif +# ifdef STA_PPSTIME { STA_PPSTIME, "ppstime" }, +# endif +# ifdef STA_FLL { STA_FLL, "fll" }, +# endif +# ifdef STA_INS { STA_INS, "ins" }, +# endif +# ifdef STA_DEL { STA_DEL, "del" }, +# endif +# ifdef STA_UNSYNC { STA_UNSYNC, "unsync" }, +# endif +# ifdef STA_FREQHOLD { STA_FREQHOLD, "freqhold" }, +# endif +# ifdef STA_PPSSIGNAL { STA_PPSSIGNAL, "ppssignal" }, +# endif +# ifdef STA_PPSJITTER { STA_PPSJITTER, "ppsjitter" }, +# endif +# ifdef STA_PPSWANDER { STA_PPSWANDER, "ppswander" }, +# endif +# ifdef STA_PPSERROR { STA_PPSERROR, "ppserror" }, +# endif +# ifdef STA_CLOCKERR { STA_CLOCKERR, "clockerr" }, +# endif # ifdef STA_NANO { STA_NANO, "nano" }, # endif @@ -214,6 +243,7 @@ static const struct codestring k_st_bits # endif /* not used with getcode(), no terminating entry needed */ }; +#endif /* HAVE_KERNEL_PLL */ /* Forwards */ static const char * getcode(int, const struct codestring *); @@ -318,10 +348,12 @@ decode_bitflags( "decode_bitflags(%s) can't decode 0x%x in %d bytes", (tab == peer_st_bits) ? "peer_st" - : + : +#ifdef HAVE_KERNEL_PLL (tab == k_st_bits) ? "kern_st" : +#endif "", (unsigned)bits, (int)LIB_BUFLENGTH); errno = saved_errno; @@ -360,6 +392,7 @@ res_access_flags( } +#ifdef HAVE_KERNEL_PLL const char * k_st_flags( uint32_t st @@ -367,6 +400,8 @@ k_st_flags( { return decode_bitflags((int)st, " ", k_st_bits, COUNTOF(k_st_bits)); } +#endif /* HAVE_KERNEL_PLL */ + /* * statustoa - return a descriptive string for a peer status --- ./ntpd/ntp_control.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./ntpd/ntp_control.c 2019-11-23 17:54:09.000000000 -0800 @@ -1359,6 +1359,7 @@ ctl_putsys( char str[256]; double dtemp; const char *ss; +#ifdef HAVE_KERNEL_PLL static struct timex ntx; static unsigned long ntp_adjtime_time; @@ -1374,6 +1375,7 @@ ctl_putsys( else ntp_adjtime_time = current_time; } +#endif /* HAVE_KERNEL_PLL */ switch (varid) { @@ -1769,50 +1771,93 @@ ctl_putsys( break; /* - * CTL_IF_KERNPPS() puts a zero if kernel hard PPS is not + * CTL_IF_KERNLOOP() puts a zero if the kernel loop is + * unavailable, otherwise calls putfunc with args. + */ +#ifndef HAVE_KERNEL_PLL +# define CTL_IF_KERNLOOP(putfunc, args) \ + ctl_putint(sys_var[varid].text, 0) +#else +# define CTL_IF_KERNLOOP(putfunc, args) \ + putfunc args +#endif + + /* + * CTL_IF_KERNPPS() puts a zero if either the kernel + * loop is unavailable, or kernel hard PPS is not * active, otherwise calls putfunc with args. */ +#ifndef HAVE_KERNEL_PLL +# define CTL_IF_KERNPPS(putfunc, args) \ + ctl_putint(sys_var[varid].text, 0) +#else # define CTL_IF_KERNPPS(putfunc, args) \ if (0 == ntx.shift) \ ctl_putint(sys_var[varid].text, 0); \ else \ putfunc args /* no trailing ; */ +#endif case CS_K_OFFSET: - ctl_putdblf(sys_var[varid].text, false, -1, - ntp_error_in_seconds(ntx.offset) * MS_PER_S); + CTL_IF_KERNLOOP( + ctl_putdblf, + (sys_var[varid].text, false, -1, + ntp_error_in_seconds(ntx.offset) * MS_PER_S) + ); break; case CS_K_FREQ: - ctl_putsfp(sys_var[varid].text, ntx.freq); + CTL_IF_KERNLOOP( + ctl_putsfp, + (sys_var[varid].text, ntx.freq) + ); break; case CS_K_MAXERR: - ctl_putdblf(sys_var[varid].text, false, 6, - ntp_error_in_seconds(ntx.maxerror) * MS_PER_S); + CTL_IF_KERNLOOP( + ctl_putdblf, + (sys_var[varid].text, false, 6, + ntp_error_in_seconds(ntx.maxerror) * MS_PER_S) + ); break; case CS_K_ESTERR: - ctl_putdblf(sys_var[varid].text, false, 6, - ntp_error_in_seconds(ntx.esterror) * MS_PER_S); + CTL_IF_KERNLOOP( + ctl_putdblf, + (sys_var[varid].text, false, 6, + ntp_error_in_seconds(ntx.esterror) * MS_PER_S) + ); break; case CS_K_STFLAGS: +#ifndef HAVE_KERNEL_PLL + ss = ""; +#else ss = k_st_flags((uint32_t)ntx.status); +#endif ctl_putstr(sys_var[varid].text, ss, strlen(ss)); break; case CS_K_TIMECONST: - ctl_putint(sys_var[varid].text, ntx.constant); + CTL_IF_KERNLOOP( + ctl_putint, + (sys_var[varid].text, ntx.constant) + ); break; case CS_K_PRECISION: - ctl_putdblf(sys_var[varid].text, false, 6, - ntp_error_in_seconds(ntx.precision) * MS_PER_S); + CTL_IF_KERNLOOP( + ctl_putdblf, + (sys_var[varid].text, false, 6, + ntp_error_in_seconds(ntx.precision) * MS_PER_S) + ); break; case CS_K_FREQTOL: - ctl_putsfp(sys_var[varid].text, ntx.tolerance); + CTL_IF_KERNLOOP( + ctl_putsfp, + (sys_var[varid].text, ntx.tolerance) + ); break; case CS_K_PPS_FREQ: --- ./ntpd/ntp_loopfilter.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./ntpd/ntp_loopfilter.c 2019-11-23 17:54:09.000000000 -0800 @@ -23,8 +23,10 @@ #define NTP_MAXFREQ 500e-6 +#ifdef HAVE_KERNEL_PLL # define FREQTOD(x) ((x) / 65536e6) /* NTP to double */ # define DTOFREQ(x) ((int32_t)((x) * 65536e6)) /* double to NTP */ +#endif /* HAVE_KERNEL_PLL */ /* * This is an implementation of the clock discipline algorithm described @@ -125,6 +127,7 @@ static void rstclock (int, double); /* t static double direct_freq(double); /* direct set frequency */ static void set_freq(double); /* set frequency */ +#ifdef HAVE_KERNEL_PLL #ifndef PATH_MAX # define PATH_MAX MAX_PATH #endif @@ -138,6 +141,7 @@ static unsigned int loop_tai; /* last TA #endif /* STA_NANO */ static void start_kern_loop(void); static void stop_kern_loop(void); +#endif /* HAVE_KERNEL_PLL */ /* * Clock state machine control flags @@ -154,7 +158,9 @@ struct clock_control_flags clock_ctl = { int freq_cnt; /* initial frequency clamp */ static int freq_set; /* initial set frequency switch */ +#ifdef HAVE_KERNEL_PLL static bool ext_enable; /* external clock enabled */ +#endif /* HAVE_KERNEL_PLL */ /* * Clock state machine variables @@ -172,6 +178,7 @@ static int sys_hufflen; /* huff-n'-puff static int sys_huffptr; /* huff-n'-puff filter pointer */ static double sys_mindly; /* huff-n'-puff filter min delay */ +#if defined(HAVE_KERNEL_PLL) /* Emacs cc-mode goes nuts if we split the next line... */ #define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \ MOD_STATUS | MOD_TIMECONST) @@ -181,7 +188,9 @@ static struct sigaction sigsys; /* curre static struct sigaction newsigsys; /* new sigaction status */ static sigjmp_buf env; /* environment var. for pll_trap() */ #endif /* SIGSYS */ +#endif /* HAVE_KERNEL_PLL */ +#ifdef HAVE_KERNEL_PLL static void sync_status(const char *what, int ostatus, int nstatus) { /* only used in non-lockclock case */ @@ -205,6 +214,7 @@ static char *file_name(void) { } return this_file; } +#endif /* HAVE_KERNEL_PLL */ /* * init_loopfilter - initialize loop filter data @@ -219,6 +229,7 @@ init_loopfilter(void) { freq_cnt = (int)clock_minstep; } +#ifdef HAVE_KERNEL_PLL /* * ntp_adjtime_error_handler - process errors from ntp_adjtime */ @@ -417,6 +428,7 @@ or, from ntp_adjtime(): } return; } +#endif /* HAVE_KERNEL_PLL */ /* * local_clock - the NTP logical clock loop filter. @@ -450,7 +462,9 @@ local_clock( int rval; /* return code */ int osys_poll; /* old system poll */ +#ifdef HAVE_KERNEL_PLL int ntp_adj_ret; /* returned by ntp_adjtime */ +#endif /* HAVE_KERNEL_PLL */ double mu; /* interval since last update */ double clock_frequency; /* clock frequency */ double dtemp, etemp; /* double temps */ @@ -707,6 +721,7 @@ local_clock( } } +#ifdef HAVE_KERNEL_PLL /* * This code segment works when clock adjustments are made using * precision time kernel support and the ntp_adjtime() system @@ -823,6 +838,7 @@ local_clock( } #endif /* STA_NANO */ } +#endif /* HAVE_KERNEL_PLL */ /* * Clamp the frequency within the tolerance range and calculate @@ -934,8 +950,10 @@ adj_host_clock( } else if (freq_cnt > 0) { offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(1)); freq_cnt--; +#ifdef HAVE_KERNEL_PLL } else if (clock_ctl.pll_control && clock_ctl.kern_enable) { offset_adj = 0.; +#endif /* HAVE_KERNEL_PLL */ } else { offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(clkstate.sys_poll)); } @@ -946,9 +964,11 @@ adj_host_clock( * set_freq(). Otherwise it is a component of the adj_systime() * offset. */ +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && clock_ctl.kern_enable) freq_adj = 0.; else +#endif /* HAVE_KERNEL_PLL */ freq_adj = loop_data.drift_comp; /* Bound absolute value of total adjustment to NTP_MAXFREQ. */ @@ -1037,6 +1057,7 @@ set_freq( loop_data.drift_comp = freq; loop_desc = "ntpd"; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control) { int ntp_adj_ret; ZERO(ntv); @@ -1049,10 +1070,12 @@ set_freq( ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, false, false, __LINE__ - 1); } } +#endif /* HAVE_KERNEL_PLL */ mprintf_event(EVNT_FSET, NULL, "%s %.6f PPM", loop_desc, loop_data.drift_comp * US_PER_S); } +#ifdef HAVE_KERNEL_PLL static void start_kern_loop(void) { @@ -1113,8 +1136,10 @@ start_kern_loop(void) "kernel time sync enabled"); } } +#endif /* HAVE_KERNEL_PLL */ +#ifdef HAVE_KERNEL_PLL static void stop_kern_loop(void) { @@ -1122,6 +1147,7 @@ stop_kern_loop(void) report_event(EVNT_KERN, NULL, "kernel time sync disabled"); } +#endif /* HAVE_KERNEL_PLL */ /* @@ -1134,11 +1160,15 @@ select_loop( { if (clock_ctl.kern_enable == use_kern_loop) return; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && !use_kern_loop) stop_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ clock_ctl.kern_enable = use_kern_loop; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && use_kern_loop) start_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ /* * If this loop selection change occurs after initial startup, * call set_freq() to switch the frequency compensation to or @@ -1194,10 +1224,12 @@ loop_config( * variables. Otherwise, continue leaving no harm behind. */ case LOOP_DRIFTINIT: +#ifdef HAVE_KERNEL_PLL if (loop_data.lockclock || clock_ctl.mode_ntpdate) break; start_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ /* * Initialize frequency if given; otherwise, begin frequency @@ -1216,11 +1248,14 @@ loop_config( rstclock(EVNT_FSET, 0); else rstclock(EVNT_NSET, 0); +#ifdef HAVE_KERNEL_PLL loop_started = true; +#endif /* HAVE_KERNEL_PLL */ break; case LOOP_KERN_CLEAR: #if 0 /* XXX: needs more review, and how can we get here? */ +# ifdef HAVE_KERNEL_PLL if (!loop_data.lockclock && (clock_ctl.pll_control && clock_ctl.kern_enable)) { memset((char *)&ntv, 0, sizeof(ntv)); ntv.modes = MOD_STATUS; @@ -1230,6 +1265,7 @@ loop_config( pll_status, ntv.status); } +# endif /* HAVE_KERNEL_PLL */ #endif break; @@ -1310,7 +1346,7 @@ loop_config( } -#if defined(SIGSYS) +#if defined(HAVE_KERNEL_PLL) && defined(SIGSYS) /* * _trap - trap processor for undefined syscalls * @@ -1328,4 +1364,4 @@ pll_trap( clock_ctl.pll_control = false; siglongjmp(env, 1); } -#endif /* SIGSYS */ +#endif /* HAVE_KERNEL_PLL && SIGSYS */ --- ./ntpd/ntp_timer.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./ntpd/ntp_timer.c 2019-11-23 17:54:09.000000000 -0800 @@ -13,7 +13,9 @@ #include <signal.h> #include <unistd.h> +#ifdef HAVE_KERNEL_PLL #include "ntp_syscall.h" +#endif /* HAVE_KERNEL_PLL */ #ifdef HAVE_TIMER_CREATE /* TC_ERR represents the timer_create() error return value. */ @@ -381,7 +383,11 @@ check_leapsec( leap_result_t lsdata; uint32_t lsprox; +#ifdef HAVE_KERNEL_PLL leapsec_electric((clock_ctl.pll_control && clock_ctl.kern_enable) ? electric_on : electric_off); +#else + leapsec_electric(electric_off); +#endif #ifdef ENABLE_LEAP_SMEAR leap_smear.enabled = (leap_smear_intv != 0); #endif --- ./ntpd/refclock_local.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./ntpd/refclock_local.c 2019-11-23 17:54:09.000000000 -0800 @@ -158,6 +158,7 @@ local_poll( * If another process is disciplining the system clock, we set * the leap bits and quality indicators from the kernel. */ +#ifdef HAVE_KERNEL_PLL if (loop_data.lockclock) { struct timex ntv; memset(&ntv, 0, sizeof ntv); @@ -188,6 +189,13 @@ local_poll( pp->disp = DISPERSION; pp->jitter = 0; } + pp->disp = 0; + pp->jitter = 0; +#else /* !HAVE_KERNEL_PLL */ + pp->leap = LEAP_NOWARNING; + pp->disp = DISPERSION; + pp->jitter = 0; +#endif /* !HAVE_KERNEL_PLL */ pp->lastref = pp->lastrec; refclock_receive(peer); } --- ./ntpfrob/precision.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./ntpfrob/precision.c 2019-11-23 17:54:09.000000000 -0800 @@ -11,6 +11,7 @@ #include "ntp_types.h" #include "ntp_calendar.h" #include "ntpfrob.h" +#include "ntp_machine.h" #define DEFAULT_SYS_PRECISION -99 --- ./tests/libntp/statestr.c.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./tests/libntp/statestr.c 2019-11-23 17:54:09.000000000 -0800 @@ -4,7 +4,9 @@ #include "unity.h" #include "unity_fixture.h" +#ifdef HAVE_SYS_TIMEX_H #include <sys/timex.h> +#endif TEST_GROUP(statestr); @@ -29,7 +31,9 @@ TEST(statestr, ResAccessFlags) { // k_st_flags() TEST(statestr, KSTFlags) { +#ifdef STA_PPSFREQ TEST_ASSERT_EQUAL_STRING("ppsfreq", k_st_flags(STA_PPSFREQ)); +#endif } // statustoa --- ./wafhelpers/bin_test.py.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./wafhelpers/bin_test.py 2019-11-23 17:54:09.000000000 -0800 @@ -97,6 +97,12 @@ def cmd_bin_test(ctx, config): if ctx.env['PYTHON_CURSES']: cmd_map_python.update(cmd_map_python_curses) + # Kludge to remove ntptime if it didn't get built + if not ctx.env.HEADER_SYS_TIMEX_H: + for cmd in list(cmd_map.keys()): + if 'ntptime' in cmd[0]: + del cmd_map[cmd] + for cmd in sorted(cmd_map): if not run(cmd, cmd_map[cmd], False): fails += 1 --- ./wafhelpers/options.py.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./wafhelpers/options.py 2019-11-23 17:54:09.000000000 -0800 @@ -19,6 +19,8 @@ def options_cmd(ctx, config): help="Droproot earlier (breaks SHM and NetBSD).") grp.add_option('--enable-seccomp', action='store_true', default=False, help="Enable seccomp (restricts syscalls).") + grp.add_option('--disable-kernel-pll', action='store_true', + default=False, help="Disable kernel PLL.") grp.add_option('--disable-mdns-registration', action='store_true', default=False, help="Disable MDNS registration.") grp.add_option( --- ./wscript.orig 2019-11-17 14:18:12.000000000 -0800 +++ ./wscript 2019-11-23 17:54:09.000000000 -0800 @@ -592,7 +592,7 @@ int main(int argc, char **argv) { structures = ( ("struct if_laddrconf", ["sys/types.h", "net/if6.h"], False), ("struct if_laddrreq", ["sys/types.h", "net/if6.h"], False), - ("struct timex", ["sys/time.h", "sys/timex.h"], True), + ("struct timex", ["sys/time.h", "sys/timex.h"], False), ("struct ntptimeval", ["sys/time.h", "sys/timex.h"], False), ) for (s, h, r) in structures: @@ -797,6 +797,21 @@ int main(int argc, char **argv) { ctx.define("HAVE_WORKING_FORK", 1, comment="Whether a working fork() exists") + # Does the kernel implement a phase-locked loop for timing? + # All modern Unixes (in particular Linux and *BSD) have this. + # + # The README for the (now deleted) kernel directory says this: + # "If the precision-time kernel (KERNEL_PLL define) is + # configured, the installation process requires the header + # file /usr/include/sys/timex.h for the particular + # architecture to be in place." + # + if ((ctx.get_define("HAVE_SYS_TIMEX_H") and + not ctx.options.disable_kernel_pll)): + ctx.define("HAVE_KERNEL_PLL", 1, + comment="Whether phase-locked loop for timing " + "exists and is enabled") + # SO_REUSEADDR socket option is needed to open a socket on an # interface when the port number is already in use on another # interface. Linux needs this, NetBSD does not, status on