Support building on macOS.
This change allows all the C++ targets to be built on OS X. (Tested with
10.12.1)
Thanks to Ben Laurie for the change.
Change-Id: I1bb6cfbe920aef2eaea7e3f7ef7c669d1218275a
diff --git a/BUILDING.md b/BUILDING.md
index b633f73..adcab35 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -2,7 +2,7 @@
## C++
-The Roughtime C++ code is built using [Bazel](https://www.bazel.io/). Everything should build on Linux. On MacOS, `simple_client` should build.
+The Roughtime C++ code is built using [Bazel](https://www.bazel.io/). Everything should build on Linux and macOS, `simple_client` should build.
In order to build, install Bazel and run `bazel build ... && bazel test ...`. That should download and build BoringSSL, gTest and Protocol Buffers automatically.
diff --git a/sys_time.cc b/sys_time.cc
index 5fa9532..c0b86df 100644
--- a/sys_time.cc
+++ b/sys_time.cc
@@ -14,16 +14,33 @@
#include "sys_time.h"
+#if defined(__MACH__)
+#include <sys/time.h>
+#else
#include <time.h>
+#endif
#include <google/protobuf/stubs/logging.h>
namespace roughtime {
+static const uint32_t kOneSecondRadius = 1000000;
+
SystemTimeSource::SystemTimeSource() {}
SystemTimeSource::~SystemTimeSource() {}
+#if defined(__MACH__)
+std::pair<rough_time_t, uint32_t> SystemTimeSource::Now() {
+ struct timeval tv;
+ GOOGLE_CHECK_EQ(0, gettimeofday(&tv, nullptr));
+ uint64_t now = tv.tv_sec;
+ now *= 1000000;
+ now += tv.tv_usec;
+
+ return std::make_pair(now, kOneSecondRadius);
+}
+#else
std::pair<rough_time_t, uint32_t> SystemTimeSource::Now() {
struct timespec ts;
GOOGLE_CHECK_EQ(0, clock_gettime(CLOCK_REALTIME_COARSE, &ts));
@@ -31,7 +48,8 @@
now *= 1000000;
now += ts.tv_nsec / 1000;
- return std::make_pair(now, 1000000);
+ return std::make_pair(now, kOneSecondRadius);
}
+#endif
} // namespace roughtime
diff --git a/udp_processor.cc b/udp_processor.cc
index 6d8cbb4..9266193 100644
--- a/udp_processor.cc
+++ b/udp_processor.cc
@@ -110,6 +110,32 @@
}
}
+#if defined(__MACH__)
+static const unsigned MSG_WAITFORONE = 0;
+
+static int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned vlen,
+ unsigned flags, struct timespec *timeout) {
+ ssize_t r = recvmsg(fd, &msgvec->msg_hdr, 0);
+ if (r < 0) {
+ return r;
+ }
+
+ msgvec->msg_len = r;
+ return 1;
+}
+
+int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned vlen, unsigned flags) {
+ GOOGLE_CHECK_EQ(1, vlen);
+ ssize_t r = sendmsg(fd, &msgvec->msg_hdr, 0);
+ if (r < 0) {
+ return r;
+ }
+
+ msgvec->msg_len = r;
+ return 1;
+}
+#endif
+
bool UdpProcessor::ProcessBatch(int fd, Server *server, Stats *out_stats) {
server->Reset();
memset(out_stats, 0, sizeof(Stats));
diff --git a/udp_processor.h b/udp_processor.h
index ba96dea..d051348 100644
--- a/udp_processor.h
+++ b/udp_processor.h
@@ -25,6 +25,14 @@
namespace roughtime {
+#if defined(__MACH__)
+struct mmsghdr {
+ uint8_t *iov_base;
+ size_t msg_len;
+ msghdr msg_hdr;
+};
+#endif
+
// UdpProcessor manages a set of receive buffers for processing UDP requests.
class UdpProcessor {
public: