From e4813f06c12a43dafcc195eb081cd571257031a6 Mon Sep 17 00:00:00 2001 From: elder-n00b <81770979+elder-n00b@users.noreply.github.com> Date: Sun, 22 Aug 2021 08:39:30 +0200 Subject: [PATCH] MacOSX legacy (#1138) * Branched v4.2 Added workaround for Mac OS X < 10.12.0 (Only tested on 10.11.6, lower versions may need more workaround) * Added *.dSYM to .gitignore * Added comments for the macosx detection in Makefile * Fixed indentation, formatting and missing newline at eof * Moved includes inside include guard Co-authored-by: elder-n00b --- .gitignore | 1 + Makefile | 17 ++++++++++++- misc/macos-legacy/mach_gettime.c | 42 ++++++++++++++++++++++++++++++++ misc/macos-legacy/mach_gettime.h | 28 +++++++++++++++++++++ src/nnn.c | 4 +++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 misc/macos-legacy/mach_gettime.c create mode 100644 misc/macos-legacy/mach_gettime.h diff --git a/.gitignore b/.gitignore index e2f3f899..a023af70 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.o +*.dSYM nnn diff --git a/Makefile b/Makefile index 5a283e4d..869a47ce 100644 --- a/Makefile +++ b/Makefile @@ -153,11 +153,26 @@ LOGO64X64 = misc/logo/logo-64x64.png GITSTATUS = patches/gitstatus NAMEFIRST = patches/namefirst +# test if we are on Mac OS X and get X.Y.Z OS version with system binary /usr/bin/sw_vers +MACOS_VERSION := $(strip $(shell command -v sw_vers >/dev/null && [ "`sw_vers -productName`" = "Mac OS X" ] && sw_vers -productVersion)) +# if Mac OS X detected, test if its version is below 10.12.0 relying on "sort -c" returning "disorder" message if the input is not sorted +ifneq ($(MACOS_VERSION),) + MACOS_BELOW_1012 := $(if $(strip $(shell printf '10.12.0\n%s' "$(MACOS_VERSION)" | sort -ct. -k1,1n -k2,2n -k3,3n 2>&1)),1) +endif +# if Mac OS X version is below 10.12.0, compile in the replacement clock_gettime and define MACOS_BELOW_1012 so that it's included in nnn.c +ifneq ($(MACOS_BELOW_1012),) + GETTIME_C = misc/macos-legacy/mach_gettime.c + GETTIME_H = misc/macos-legacy/mach_gettime.h + SRC += $(GETTIME_C) + HEADERS += $(GETTIME_H) + CPPFLAGS += -DMACOS_BELOW_1012 +endif + all: $(BIN) $(BIN): $(SRC) $(HEADERS) @$(MAKE) --silent prepatch - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(GETTIME_C) $< $(LDLIBS) @$(MAKE) --silent postpatch # targets for backwards compatibility diff --git a/misc/macos-legacy/mach_gettime.c b/misc/macos-legacy/mach_gettime.c new file mode 100644 index 00000000..a52bb84d --- /dev/null +++ b/misc/macos-legacy/mach_gettime.c @@ -0,0 +1,42 @@ +#include "mach_gettime.h" +#include + +#define MT_NANO (+1.0E-9) +#define MT_GIGA UINT64_C(1000000000) + +// TODO create a list of timers, +static double mt_timebase = 0.0; +static uint64_t mt_timestart = 0; + +int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + kern_return_t retval = KERN_SUCCESS; + + if (clk_id == TIMER_ABSTIME) { + if (!mt_timestart) { // only one timer, initialized on the first call to the TIMER + mach_timebase_info_data_t tb; + mach_timebase_info(&tb); + mt_timebase = tb.numer; + mt_timebase /= tb.denom; + mt_timestart = mach_absolute_time(); + } + + double diff = (mach_absolute_time() - mt_timestart) * mt_timebase; + tp->tv_sec = diff * MT_NANO; + tp->tv_nsec = diff - (tp->tv_sec * MT_GIGA); + } else { // other clk_ids are mapped to the coresponding mach clock_service + clock_serv_t cclock; + mach_timespec_t mts; + + host_get_clock_service(mach_host_self(), clk_id, &cclock); + retval = clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + + tp->tv_sec = mts.tv_sec; + tp->tv_nsec = mts.tv_nsec; + } + + return retval; +} + +/* Copyright (c) 2015-2018 Alf Watt - Open Source - https://opensource.org/licenses/MIT */ diff --git a/misc/macos-legacy/mach_gettime.h b/misc/macos-legacy/mach_gettime.h new file mode 100644 index 00000000..cf574d4a --- /dev/null +++ b/misc/macos-legacy/mach_gettime.h @@ -0,0 +1,28 @@ +#ifndef mach_time_h +#define mach_time_h + +#include +#include +#include +#include + +/* The opengroup spec isn't clear on the mapping from REALTIME to CALENDAR + being appropriate or not. + http://pubs.opengroup.org/onlinepubs/009695299/basedefs/time.h.html */ + +// XXX only supports a single timer +#define TIMER_ABSTIME -1 +#define CLOCK_REALTIME CALENDAR_CLOCK +#define CLOCK_MONOTONIC SYSTEM_CLOCK + +typedef int clockid_t; + +/* the mach kernel uses struct mach_timespec, so struct timespec + is loaded from for compatability */ +// struct timespec { time_t tv_sec; long tv_nsec; }; + +int clock_gettime(clockid_t clk_id, struct timespec *tp); + +#endif + +/* Copyright (c) 2015-2018 Alf Watt - Open Source - https://opensource.org/licenses/MIT */ diff --git a/src/nnn.c b/src/nnn.c index 5dc55dd7..b15a1199 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -108,6 +108,10 @@ #include #include +#ifdef MACOS_BELOW_1012 +#include "../misc/macos-legacy/mach_gettime.h" +#endif + #if !defined(alloca) && defined(__GNUC__) /* * GCC doesn't expand alloca() to __builtin_alloca() in standards mode