aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Drewry <wad@chromium.org>2014-09-17 15:33:22 -0500
committerWill Drewry <wad@chromium.org>2014-09-17 15:33:22 -0500
commit9c331bf201909fb5a85725202eee872d4323e12d (patch)
tree5ff4b6a52c6a595a28c1c99e0baf573431c64241
parent7daea59e81770f9ba5f1ba2b04d7f31b4828e5fc (diff)
downloadtlsdate-9c331bf201909fb5a85725202eee872d4323e12d.tar.gz
continued merge issues: platform, debug, configs
- moved debug () to verb_debug () - moved to platform->* calls for system calls - moved upstart file for cros to a cros-specific name
-rw-r--r--init/tlsdated-cros.conf (renamed from init/tlsdated.conf)0
-rw-r--r--src/dbus.c27
-rw-r--r--src/dbus.h6
-rw-r--r--src/events/kickoff_time_sync.c10
-rw-r--r--src/events/route_up.c6
-rw-r--r--src/events/run_tlsdate.c2
-rw-r--r--src/events/save.c2
-rw-r--r--src/events/sigchld.c2
-rw-r--r--src/events/sigterm.c2
-rw-r--r--src/events/time_set.c2
-rw-r--r--src/events/tlsdate_status.c2
-rw-r--r--src/platform-cros.c16
-rw-r--r--src/rtc.h9
-rw-r--r--src/seccomp.c1
-rw-r--r--src/tlsdate-helper.c2
-rw-r--r--src/tlsdate-monitor.c2
-rw-r--r--src/tlsdate-setter.c42
-rw-r--r--src/tlsdate.h5
-rw-r--r--src/tlsdated-unittest.c67
-rw-r--r--src/tlsdated.c39
-rw-r--r--src/util.c150
-rw-r--r--src/util.h35
-rw-r--r--tests/run-idle/runs2
-rw-r--r--tests/run-routeup/runs2
24 files changed, 173 insertions, 260 deletions
diff --git a/init/tlsdated.conf b/init/tlsdated-cros.conf
index f5b46a4..f5b46a4 100644
--- a/init/tlsdated.conf
+++ b/init/tlsdated-cros.conf
diff --git a/src/dbus.c b/src/dbus.c
index 81bda4b..b83e9ef 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -231,15 +231,21 @@ toggle_timeout (DBusTimeout *t, void *user_data)
}
}
-#ifdef TLSDATED_MAIN
void
dbus_announce (struct state *global_state)
{
struct dbus_state *state = global_state->dbus;
- DBusConnection *conn = state->conn;
+ DBusConnection *conn;
DBusMessage *msg;
uint32_t ignored;
const char *sync_type = sync_type_str (global_state->last_sync_type);
+
+#ifndef TLSDATED_MAIN
+ /* Return early if we're not linked to tlsdated. */
+ return;
+#endif
+
+ conn = state->conn;
msg = dbus_message_new_signal (kServicePath, kServiceInterface, kTimeUpdated);
if (!msg)
{
@@ -259,7 +265,6 @@ dbus_announce (struct state *global_state)
return;
}
}
-#endif
static
DBusHandlerResult
@@ -374,7 +379,7 @@ handle_set_time (DBusConnection *connection,
DBusMessageIter iter;
DBusError error;
dbus_int64_t requested_time = 0;
- debug ("[event:%s]: fired", __func__);
+ verb_debug ("[event:%s]: fired", __func__);
dbus_error_init (&error);
/* Expects DBUS_TYPE_INT64:<time_t> */
@@ -410,7 +415,7 @@ handle_can_set_time (DBusConnection *connection,
DBusMessage *message,
struct state *state)
{
- debug ("[event:%s]: fired", __func__);
+ verb_debug ("[event:%s]: fired", __func__);
return send_can_reply (connection, message, can_set_time (state));
}
@@ -427,7 +432,7 @@ handle_last_sync_info (DBusConnection *connection,
const char *sync = sync_type_str (state->last_sync_type);
int64_t t = state->last_time;
- debug ("[dbus]: handler fired");
+ verb_debug ("[dbus]: handler fired");
reply = dbus_message_new_method_return (message);
if (!reply)
{
@@ -488,7 +493,7 @@ service_dispatch (DBusConnection *conn, DBusMessage *msg, void *data)
const char *interface;
const char *method;
- debug ("[dbus] service dispatcher called");
+ verb_debug ("[dbus] service dispatcher called");
if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_METHOD_CALL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -496,13 +501,13 @@ service_dispatch (DBusConnection *conn, DBusMessage *msg, void *data)
method = dbus_message_get_member (msg);
if (!interface || !method)
{
- debug ("[dbus] service request fired with bogus data");
+ verb_debug ("[dbus] service request fired with bogus data");
/* Consume it */
return DBUS_HANDLER_RESULT_HANDLED;
}
if (strcmp (interface, kServiceInterface))
{
- debug ("[dbus] invalid interface supplied");
+ verb_debug ("[dbus] invalid interface supplied");
return DBUS_HANDLER_RESULT_HANDLED;
}
if (!strcmp (method, kServiceSetTime))
@@ -511,7 +516,7 @@ service_dispatch (DBusConnection *conn, DBusMessage *msg, void *data)
return handle_can_set_time (conn, msg, state);
else if (!strcmp (method, kServiceLastSyncInfo))
return handle_last_sync_info (conn, msg, state);
- debug ("[dbus] invalid method supplied");
+ verb_debug ("[dbus] invalid method supplied");
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
@@ -564,7 +569,7 @@ init_dbus (struct state *tlsdate_state)
goto err;
}
- debug ("[dbus] initialized");
+ verb_debug ("[dbus] initialized");
return 0;
err:
tlsdate_state->dbus = NULL;
diff --git a/src/dbus.h b/src/dbus.h
index b166a7d..296ba86 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -31,13 +31,7 @@ struct dbus_event_data
struct event *event;
};
-#ifdef TLSDATED_MAIN
void dbus_announce (struct state *);
-#else
-static inline void dbus_announce (struct state *global_state)
-{
-}
-#endif
#else /* !HAVE_DBUS */
struct state;
diff --git a/src/events/kickoff_time_sync.c b/src/events/kickoff_time_sync.c
index 33c15ed..2ed2b0b 100644
--- a/src/events/kickoff_time_sync.c
+++ b/src/events/kickoff_time_sync.c
@@ -70,7 +70,7 @@ void
action_invalidate_time (evutil_socket_t fd, short what, void *arg)
{
struct state *state = arg;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
/* If time is already invalid and being acquired, do nothing. */
if (state->last_sync_type == SYNC_TYPE_RTC &&
event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL))
@@ -118,7 +118,7 @@ setup_event_timer_sync (struct state *state)
void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg)
{
struct state *state = arg;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
time_t delta = state->clock_delta;
int jitter = 0;
if (check_continuity (&delta) > 0)
@@ -134,7 +134,7 @@ void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg)
}
if (state->last_sync_type == SYNC_TYPE_NET)
{
- debug ("[event:%s] time in sync. skipping", __func__);
+ verb_debug ("[event:%s] time in sync. skipping", __func__);
return;
}
/* Keep parity with run_tlsdate: for every wake, allow it to retry again. */
@@ -142,7 +142,7 @@ void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg)
{
state->tries -= 1;
/* Don't bother re-triggering tlsdate */
- debug ("[event:%s] called while tries are in progress", __func__);
+ verb_debug ("[event:%s] called while tries are in progress", __func__);
return;
}
/* Don't over-schedule if the first attempt hasn't fired. If a wake event
@@ -152,7 +152,7 @@ void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg)
*/
if (event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL))
{
- debug ("[event:%s] called while tlsdate is pending", __func__);
+ verb_debug ("[event:%s] called while tlsdate is pending", __func__);
return;
}
if (!state->events[E_RESOLVER])
diff --git a/src/events/route_up.c b/src/events/route_up.c
index 280467d..23330bd 100644
--- a/src/events/route_up.c
+++ b/src/events/route_up.c
@@ -23,7 +23,7 @@ void action_stdin_wakeup (evutil_socket_t fd, short what, void *arg)
{
struct state *state = arg;
char buf[1];
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
if (what != EV_READ)
return;
if (IGNORE_EINTR (read (fd, buf, sizeof (buf))) != sizeof (buf))
@@ -40,13 +40,13 @@ void action_stdin_wakeup (evutil_socket_t fd, short what, void *arg)
void action_netlink_ready (evutil_socket_t fd, short what, void *arg)
{
struct routeup routeup_cfg;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
routeup_cfg.netlinkfd = fd;
if (what & EV_READ)
{
if (routeup_process (&routeup_cfg) == 0)
{
- debug ("[event:%s] routes changed", __func__);
+ verb_debug ("[event:%s] routes changed", __func__);
/* Fire off a proxy resolution attempt and a new sync request */
action_kickoff_time_sync (-1, EV_TIMEOUT, arg);
}
diff --git a/src/events/run_tlsdate.c b/src/events/run_tlsdate.c
index c36da16..86f1236 100644
--- a/src/events/run_tlsdate.c
+++ b/src/events/run_tlsdate.c
@@ -18,7 +18,7 @@
void action_run_tlsdate (evutil_socket_t fd, short what, void *arg)
{
struct state *state = arg;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
if (state->last_sync_type == SYNC_TYPE_NET)
{
info ("[event:%s] called, but network time isn't needed");
diff --git a/src/events/save.c b/src/events/save.c
index 637952a..8fa733e 100644
--- a/src/events/save.c
+++ b/src/events/save.c
@@ -23,7 +23,7 @@ void action_sync_and_save (evutil_socket_t fd, short what, void *arg)
struct state *state = arg;
time_t t = state->last_time;
ssize_t bytes;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
/* For all non-net sources, don't write to disk by
* flagging the time negative. We don't use negative
* times and this won't effect shutdown (0) writes.
diff --git a/src/events/sigchld.c b/src/events/sigchld.c
index e164f2e..b4078b5 100644
--- a/src/events/sigchld.c
+++ b/src/events/sigchld.c
@@ -114,7 +114,7 @@ void
action_sigchld (evutil_socket_t fd, short what, void *arg)
{
struct state *state = arg;
- debug ("[event:%s] a child process has SIGCHLD'd!", __func__);
+ verb_debug ("[event:%s] a child process has SIGCHLD'd!", __func__);
/* Process SIGCHLDs in two steps: death and stopped until all
* pending children are sorted.
*/
diff --git a/src/events/sigterm.c b/src/events/sigterm.c
index 0143d6f..ff09ab8 100644
--- a/src/events/sigterm.c
+++ b/src/events/sigterm.c
@@ -22,7 +22,7 @@ void action_sigterm (evutil_socket_t fd, short what, void *arg)
struct timeval tv;
info ("[event:%s] starting graceful shutdown . . .", __func__);
state->exitting = 1;
- if (gettimeofday (&tv, NULL))
+ if (platform->time_get (&tv))
{
pfatal ("[event:%s] couldn't gettimeofday to exit gracefully", __func__);
}
diff --git a/src/events/time_set.c b/src/events/time_set.c
index 36f518f..edc30c9 100644
--- a/src/events/time_set.c
+++ b/src/events/time_set.c
@@ -86,7 +86,7 @@ action_time_set (evutil_socket_t fd, short what, void *arg)
struct state *state = arg;
int status = -1;
ssize_t bytes = 0;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
bytes = IGNORE_EINTR (read (fd, &status, sizeof (status)));
if (bytes == -1 && errno == EAGAIN)
return; /* Catch next wake up */
diff --git a/src/events/tlsdate_status.c b/src/events/tlsdate_status.c
index caa71fd..3e7601c 100644
--- a/src/events/tlsdate_status.c
+++ b/src/events/tlsdate_status.c
@@ -61,7 +61,7 @@ action_tlsdate_status (evutil_socket_t fd, short what, void *arg)
struct state *state = arg;
time_t t = 0;
int ret = read_tlsdate_response (fd, &t);
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
if (ret < 0)
{
trigger_event (state, E_TLSDATE_TIMEOUT, 0);
diff --git a/src/platform-cros.c b/src/platform-cros.c
index 56c7115..5a9d7ab 100644
--- a/src/platform-cros.c
+++ b/src/platform-cros.c
@@ -192,7 +192,7 @@ handle_service_change (DBusConnection *connection,
const char *pval;
const char *service;
dbus_error_init (&error);
- debug ("[event:cros:%s]: fired", __func__);
+ verb_debug ("[event:cros:%s]: fired", __func__);
/* TODO(wad) Track the current DefaultService only fire when it changes */
service = dbus_message_get_path (message);
if (!service)
@@ -232,7 +232,7 @@ handle_manager_change (DBusConnection *connection,
DBusError error;
const char *pname;
const char *pval;
- debug ("[event:cros:%s]: fired", __func__);
+ verb_debug ("[event:cros:%s]: fired", __func__);
dbus_error_init (&error);
if (!dbus_message_iter_init (message, &iter))
return DBUS_HANDLER_RESULT_HANDLED;
@@ -251,7 +251,7 @@ handle_manager_change (DBusConnection *connection,
return DBUS_HANDLER_RESULT_HANDLED;
dbus_message_iter_get_basic (&subiter, &pval);
/* TODO(wad) Filter on the currently active service in pval. */
- debug ("[event:cros:%s] service change on path %s",
+ verb_debug ("[event:cros:%s] service change on path %s",
__func__, pval);
action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
return DBUS_HANDLER_RESULT_HANDLED;
@@ -266,7 +266,7 @@ handle_suspend_done (DBusConnection *connection,
DBusMessageIter iter;
DBusError error;
const char *pname;
- debug ("[event:cros:%s]: fired", __func__);
+ verb_debug ("[event:cros:%s]: fired", __func__);
/* Coming back from resume, trigger a continuity and time
* check just in case none of the other events happen.
*/
@@ -287,7 +287,7 @@ handle_proxy_change (DBusConnection *connection,
char time_host[MAX_PROXY_URL];
int url_len = 0;
struct source *src = ctx->state->opts.sources;
- debug ("[event:cros:%s]: fired", __func__);
+ verb_debug ("[event:cros:%s]: fired", __func__);
if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
src = ctx->state->opts.cur_source->next;
if (!ctx->state->resolving)
@@ -337,7 +337,7 @@ handle_dbus_change (DBusConnection *connection,
DBusMessageIter iter;
DBusError error;
const char *pname;
- debug ("[event:cros:%s]: fired", __func__);
+ verb_debug ("[event:cros:%s]: fired", __func__);
dbus_error_init (&error);
if (!dbus_message_iter_init (message, &iter))
return DBUS_HANDLER_RESULT_HANDLED;
@@ -359,7 +359,7 @@ action_resolve_proxy (evutil_socket_t fd, short what, void *arg)
struct dbus_state *dbus_state = ctx->state->dbus;
DBusConnection *conn = dbus_state->conn;
struct source *src = ctx->state->opts.sources;
- debug ("[event:%s] fired", __func__);
+ verb_debug ("[event:%s] fired", __func__);
/* Emulate tlsdate-monitor.c:build_argv and choose the next source */
if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
src = ctx->state->opts.cur_source->next;
@@ -447,7 +447,7 @@ dbus_filter (DBusConnection *connection, DBusMessage *message, void *data)
info ("[cros] unknown DBus METHOD_RETURN seen: %u", serial);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- debug ("[cros] unknown message received: "
+ verb_debug ("[cros] unknown message received: "
"type=%s dest=%s interface=%s member=%s path=%s sig=%s error_name=%s",
dbus_message_type_to_string (dbus_message_get_type (message)),
dbus_message_get_destination (message),
diff --git a/src/rtc.h b/src/rtc.h
new file mode 100644
index 0000000..2017e96
--- /dev/null
+++ b/src/rtc.h
@@ -0,0 +1,9 @@
+#ifndef RTC_H
+#define RTC_H
+
+struct rtc_handle
+{
+ int fd;
+};
+
+#endif /* RTC_H */
diff --git a/src/seccomp.c b/src/seccomp.c
index bc25e4c..7a7b904 100644
--- a/src/seccomp.c
+++ b/src/seccomp.c
@@ -88,7 +88,6 @@ enable_setter_seccomp (void)
SC_ALLOW (write),
SC_ALLOW (pwritev),
SC_ALLOW (ioctl), /* TODO(wad) filter for fd and RTC_SET_TIME */
- SC_ALLOW (restart_syscall),
SC_ALLOW (exit_group),
SC_ALLOW (exit),
BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
diff --git a/src/tlsdate-helper.c b/src/tlsdate-helper.c
index eea4b00..e193b22 100644
--- a/src/tlsdate-helper.c
+++ b/src/tlsdate-helper.c
@@ -1356,7 +1356,7 @@ main(int argc, char **argv)
(void) munmap (time_map, sizeof (uint32_t));
_exit (0);
}
- if (ssl_child != waitpid (ssl_child, &status, 0))
+ if (ssl_child != platform->process_wait (ssl_child, &status, 1))
die ("waitpid failed: %s\n", strerror (errno));
if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)) ))
die ("child process failed in SSL handshake\n");
diff --git a/src/tlsdate-monitor.c b/src/tlsdate-monitor.c
index 26b4394..032fbe1 100644
--- a/src/tlsdate-monitor.c
+++ b/src/tlsdate-monitor.c
@@ -81,7 +81,7 @@ tlsdate (struct state *state)
perror ("fork() failed!");
return -1;
default:
- debug ("[tlsdate-monitor] spawned tlsdate: %d", pid);
+ verb_debug ("[tlsdate-monitor] spawned tlsdate: %d", pid);
state->tlsdate_pid = pid;
return 0;
}
diff --git a/src/tlsdate-setter.c b/src/tlsdate-setter.c
index d14a2f2..179327e 100644
--- a/src/tlsdate-setter.c
+++ b/src/tlsdate-setter.c
@@ -9,14 +9,12 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/rtc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/types.h>
-#include <sys/uio.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -32,43 +30,7 @@
int
save_timestamp_to_fd (int fd, time_t t)
{
- struct iovec iov[1];
- ssize_t ret;
- iov[0].iov_base = &t;
- iov[0].iov_len = sizeof (t);
- ret = IGNORE_EINTR (pwritev (fd, iov, 1, 0));
- /* TODO(wad) platform->file_write(path, &t, sizeof(t)) */
- if (ret != sizeof (t))
- return 1;
- return 0;
-}
-
-/*
- * Set the hardware clock referred to by fd (which should be a descriptor to
- * some device that implements the interface documented in rtc(4)) to the system
- * time. See hwclock(8) for details of why this is important. If we fail, we
- * just return - there's nothing the caller can really do about a failure of
- * this function except try later.
- */
-int
-sync_hwclock (int fd, time_t sec)
-{
- struct tm tm;
- struct rtc_time rtctm;
- /* TODO(wad) if (platform->time_get(&tv)) */
- gmtime_r (&sec, &tm);
- /* these structs are identical, but separately defined */
- rtctm.tm_sec = tm.tm_sec;
- rtctm.tm_min = tm.tm_min;
- rtctm.tm_hour = tm.tm_hour;
- rtctm.tm_mday = tm.tm_mday;
- rtctm.tm_mon = tm.tm_mon;
- rtctm.tm_year = tm.tm_year;
- rtctm.tm_wday = tm.tm_wday;
- rtctm.tm_yday = tm.tm_yday;
- rtctm.tm_isdst = tm.tm_isdst;
- /* TODO(wad) if (platform->rtc_write(rtc_handle, &tv)) */
- return ioctl (fd, RTC_SET_TIME, &rtctm);
+ return platform->file_write(fd, &t, sizeof (t));
}
void
@@ -190,7 +152,7 @@ time_setter_coprocess (int time_fd, int notify_fd, struct state *state)
goto notify_and_die;
}
if (state->opts.should_sync_hwclock &&
- sync_hwclock (state->hwclock_fd, tv.tv_sec))
+ platform->rtc_write(&state->hwclock, &tv))
{
status = SETTER_NO_RTC;
goto notify_and_die;
diff --git a/src/tlsdate.h b/src/tlsdate.h
index 6f9f799..228a342 100644
--- a/src/tlsdate.h
+++ b/src/tlsdate.h
@@ -22,6 +22,8 @@
#include <time.h>
#include <unistd.h>
+#include "src/rtc.h"
+
#define DEFAULT_HOST "www.ptb.de"
#define DEFAULT_PORT "443"
#define DEFAULT_PROXY "none"
@@ -153,6 +155,7 @@ enum event_id_t
};
struct event_base;
+
/* This struct is used for passing tlsdated runtime state between
* events/ in its event loop.
*/
@@ -168,7 +171,7 @@ struct state
time_t last_time;
char timestamp_path[PATH_MAX];
- int hwclock_fd;
+ struct rtc_handle hwclock;
char dynamic_proxy[MAX_PROXY_URL];
/* Event triggered events */
diff --git a/src/tlsdated-unittest.c b/src/tlsdated-unittest.c
index 0e22ee3..3c2986a 100644
--- a/src/tlsdated-unittest.c
+++ b/src/tlsdated-unittest.c
@@ -184,7 +184,7 @@ runner (FIXTURE_DATA (tlsdate) *self, time_t *newtime)
return 1;
}
-TEST_F (tlsdate, runner)
+TEST_F (tlsdate, runner_multi)
{
struct source source =
{
@@ -325,69 +325,12 @@ FIXTURE_TEARDOWN(mock_platform) {
/* TODO(wad) add a leap test. */
-/*
- * The stuff below this line is ugly. For a lot of these mock functions, we want
- * to smuggle some state (our success) back to the caller, but there's no angle
- * for that, so we're basically stuck with some static variables to store
- * expectations and successes/failures. This could also be done with nested
- * functions, but only gcc supports them.
- */
-static const time_t sync_hwclock_expected = 12345678;
-
-static int sync_hwclock_time_get(struct timeval *tv) {
- tv->tv_sec = sync_hwclock_expected;
- tv->tv_usec = 0;
- return 0;
-}
-
-static int sync_hwclock_rtc_write(void *handle, const struct timeval *tv) {
- *(int *)handle = tv->tv_sec == sync_hwclock_expected;
- return 0;
-}
-
-/* TODO(wad)
-TEST_F(mock_platform, sync_hwclock) {
- int ok = 0;
- void *fake_handle = (void *)&ok;
+TEST_F(mock_platform, time_setter) {
+ /*
self->platform.time_get = sync_hwclock_time_get;
self->platform.rtc_write = sync_hwclock_rtc_write;
- sync_hwclock(fake_handle);
- ASSERT_EQ(ok, 1);
-}
-*/
-
-static const time_t sync_and_save_expected = 12345678;
-
-static int sync_and_save_time_get(struct timeval *tv) {
- tv->tv_sec = sync_and_save_expected;
- tv->tv_usec = 0;
- return 0;
-}
-
-static int sync_and_save_rtc_write(void *handle, const struct timeval *tv) {
- *(int *)handle += tv->tv_sec == sync_and_save_expected;
- return 0;
-}
-
-static int sync_and_save_file_write_ok = 0;
-
-static int sync_and_save_file_write(const char *path, void *buf, size_t sz) {
- if (!strcmp(path, timestamp_path))
- sync_and_save_file_write_ok++;
- return 0;
-}
-
-/* TODO(wad) TODO ?
-TEST_F(mock_platform, sync_and_save) {
- int nosave_ok = 0;
- self->platform.time_get = sync_and_save_time_get;
- self->platform.rtc_write = sync_and_save_rtc_write;
- self->platform.file_write = sync_and_save_file_write;
- sync_and_save(&sync_and_save_file_write_ok, 1);
- ASSERT_EQ(sync_and_save_file_write_ok, 2);
- sync_and_save(&nosave_ok, 0);
- ASSERT_EQ(nosave_ok, 1);
+ */
+ ASSERT_EQ(0, 1);
}
-*/
TEST_HARNESS_MAIN
diff --git a/src/tlsdated.c b/src/tlsdated.c
index ad4f4ca..09a5489 100644
--- a/src/tlsdated.c
+++ b/src/tlsdated.c
@@ -29,7 +29,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
-#include <sys/uio.h>
#include <time.h>
#include <unistd.h>
@@ -59,30 +58,20 @@ is_sane_time (time_t ts)
int
load_disk_timestamp (const char *path, time_t * t)
{
-/* TODO(wad)
- time_t tmpt;
- if (platform->file_read(path, &tmpt, sizeof(tmpt))) {
- info("can't load time file");
- return -1;
- }
-*/
- struct iovec iov[1];
- int fd = open (path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
- time_t tmpt;
- iov[0].iov_base = &tmpt;
- iov[0].iov_len = sizeof (tmpt);
+ int fd = platform->file_open (path, 0 /* RDONLY */, 1 /* CLOEXEC */);
+ time_t tmpt = 0;
if (fd < 0)
{
perror ("Can't open %s for reading", path);
return -1;
}
- if (preadv (fd, iov, 1, 0) != sizeof (tmpt))
+ if (platform->file_read(fd, &tmpt, sizeof(tmpt)))
{
perror ("Can't read seconds from %s", path);
- close (fd);
+ platform->file_close (fd);
return -1;
}
- close (fd);
+ platform->file_close (fd);
if (!is_sane_time (tmpt))
{
error ("Disk timestamp is not sane: %ld", tmpt);
@@ -425,19 +414,19 @@ cleanup_main (struct state *state)
}
}
/* The other half was closed above. */
- close (state->tlsdate_monitor_fd);
+ platform->file_close (state->tlsdate_monitor_fd);
if (state->tlsdate_pid)
{
- kill (state->tlsdate_pid, SIGKILL);
- waitpid (state->tlsdate_pid, NULL, WNOHANG);
+ platform->process_signal (state->tlsdate_pid, SIGKILL);
+ platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */);
}
/* Best effort to tear it down if it is still alive. */
close(state->setter_notify_fd);
close(state->setter_save_fd);
if (state->setter_pid)
{
- kill (state->setter_pid, SIGKILL);
- waitpid (state->setter_pid, NULL, WNOHANG);
+ platform->process_signal (state->setter_pid, SIGKILL);
+ platform->process_wait (state->setter_pid, NULL, 0 /* !forever */);
}
/* TODO(wad) Add dbus_cleanup() */
if (state->base)
@@ -473,12 +462,11 @@ main (int argc, char *argv[], char *envp[])
add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY);
state.base = base;
state.envp = envp;
- state.hwclock_fd = -1;
state.backoff = state.opts.wait_between_tries;
/* TODO(wad) move this into setup_time_setter */
- /* grab a handle to /dev/rtc for sync_hwclock() */
+ /* grab a handle to /dev/rtc for time-setter. */
if (state.opts.should_sync_hwclock &&
- (state.hwclock_fd = open (DEFAULT_RTC_DEVICE, O_RDONLY)) < 0)
+ platform->rtc_open(&state.hwclock))
{
pinfo ("can't open hwclock fd");
state.opts.should_sync_hwclock = 0;
@@ -497,8 +485,7 @@ main (int argc, char *argv[], char *envp[])
goto out;
}
/* release the hwclock now that the time-setter is running. */
- close (state.hwclock_fd);
- state.hwclock_fd = -1;
+ platform->rtc_close (&state.hwclock);
/* drop privileges before touching any untrusted data */
drop_privs_to (state.opts.user, state.opts.group);
/* register a signal handler to save time at shutdown */
diff --git a/src/util.c b/src/util.c
index 9c06e73..f9fb8ca 100644
--- a/src/util.c
+++ b/src/util.c
@@ -23,6 +23,7 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <sys/wait.h>
#include <syslog.h>
#include <time.h>
@@ -136,30 +137,34 @@ drop_privs_to (const char *user, const char *group)
}
#ifdef ENABLE_RTC
-struct rtc_handle
+int rtc_open(struct rtc_handle *h)
{
- int fd;
-};
-
-void *rtc_open()
-{
- struct rtc_handle *h = malloc(sizeof *h);
+ if (!h)
+ return -1;
+ h->fd = -1;
+ /* TODO: Use platform->file_open but drop NOFOLLOW? */
h->fd = open(DEFAULT_RTC_DEVICE, O_RDONLY);
if (h->fd < 0)
- {
+ {
pinfo("can't open rtc");
- free(h);
- return NULL;
+ return -1;
}
- return h;
+ return 0;
}
-int rtc_write(void *handle, const struct timeval *tv)
+/*
+ * Set the hardware clock referred to by fd (which should be a descriptor to
+ * some device that implements the interface documented in rtc(4)) to the system
+ * time. See hwclock(8) for details of why this is important. If we fail, we
+ * just return - there's nothing the caller can really do about a failure of
+ * this function except try later.
+ */
+int rtc_write(struct rtc_handle *handle, const struct timeval *tv)
{
struct tm tmr;
struct tm *tm;
struct rtc_time rtctm;
- int fd = ((struct rtc_handle *)handle)->fd;
+ int fd = handle->fd;
tm = gmtime_r (&tv->tv_sec, &tmr);
@@ -184,11 +189,11 @@ int rtc_write(void *handle, const struct timeval *tv)
return 0;
}
-int rtc_read(void *handle, struct timeval *tv)
+int rtc_read(struct rtc_handle *handle, struct timeval *tv)
{
struct tm tm;
struct rtc_time rtctm;
- int fd = ((struct rtc_handle *)handle)->fd;
+ int fd = handle->fd;
if (ioctl (fd, RTC_RD_TIME, &rtctm))
{
@@ -212,75 +217,72 @@ int rtc_read(void *handle, struct timeval *tv)
return 0;
}
-int rtc_close(void *handle)
+int rtc_close(struct rtc_handle *handle)
{
struct rtc_handle *h = handle;
- close(h->fd);
- free(h);
+ platform->file_close(h->fd);
+ h->fd = -1;
return 0;
}
#endif
-int file_write(const char *path, void *buf, size_t sz)
+int file_write(int fd, void *buf, size_t sz)
{
- char tmp[PATH_MAX];
- int oflags = O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC;
- int perms = S_IRUSR | S_IWUSR;
- int fd;
-
- if (snprintf(tmp, sizeof(tmp), path, kTempSuffix) >= sizeof(tmp))
- {
- pinfo("path %s too long to use", path);
- exit(1);
- }
-
- if ((fd = open(tmp, oflags, perms)) < 0)
- {
- pinfo("open(%s) failed", tmp);
- return 1;
- }
-
- if (write(fd, buf, sz) != sz)
- {
- pinfo("write() failed");
- close(fd);
- return 1;
- }
-
- if (close(fd))
- {
- pinfo("close() failed");
- return 1;
- }
-
- if (rename(tmp, path))
- {
- pinfo("rename() failed");
- return 1;
+ struct iovec iov[1];
+ ssize_t ret;
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sz;
+ ret = IGNORE_EINTR (pwritev (fd, iov, 1, 0));
+ if (ret != sz)
+ {
+ return -1;
}
-
return 0;
}
-int file_read(const char *path, void *buf, size_t sz)
+int file_open(const char *path, int write, int cloexec)
{
- int fd = open(path, O_RDONLY | O_NOFOLLOW);
+ int fd;
+ int oflags = cloexec ? O_CLOEXEC : 0;
+ if (write)
+ {
+ int perms = S_IRUSR | S_IWUSR;
+ oflags |= O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC;
+ /* Rely on atomic write calls rather than rename() calls. */
+ fd = open(path, oflags, perms);
+ }
+ else
+ {
+ oflags |= O_RDONLY | O_NOFOLLOW;
+ fd = open(path, oflags);
+ }
if (fd < 0)
- {
+ {
pinfo("open(%s) failed", path);
- return 1;
- }
-
- if (read(fd, buf, sz) != sz)
- {
- pinfo("read() failed");
- close(fd);
- return 1;
+ return -1;
}
+ return fd;
+}
+int file_close(int fd)
+{
return close(fd);
}
+int file_read(int fd, void *buf, size_t sz)
+{
+ struct iovec iov[1];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sz;
+ if (preadv (fd, iov, 1, 0) != sz)
+ {
+ /* Returns -1 on read failure */
+ return -1;
+ }
+ /* Returns 0 on a successful buffer fill. */
+ return 0;
+}
+
int time_get(struct timeval *tv)
{
return gettimeofday(tv, NULL);
@@ -297,6 +299,17 @@ int pgrp_kill(void)
return kill(-grp, SIGKILL);
}
+int process_signal(pid_t pid, int signal)
+{
+ return kill (pid, signal);
+}
+
+pid_t process_wait(pid_t pid, int *status, int forever)
+{
+ int flag = forever ? 0 : WNOHANG;
+ return waitpid (pid, status, flag);
+}
+
static struct platform default_platform = {
#ifdef ENABLE_RTC
.rtc_open = rtc_open,
@@ -305,13 +318,18 @@ static struct platform default_platform = {
.rtc_close = rtc_close,
#endif
+ .file_open = file_open,
+ .file_close = file_close,
.file_write = file_write,
.file_read = file_read,
.time_get = time_get,
.pgrp_enter = pgrp_enter,
- .pgrp_kill = pgrp_kill
+ .pgrp_kill = pgrp_kill,
+
+ .process_signal = process_signal,
+ .process_wait = process_wait
};
struct platform *platform = &default_platform;
diff --git a/src/util.h b/src/util.h
index 2d7efb6..b0600c3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -13,6 +13,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include "src/rtc.h"
+
#ifdef TARGET_OS_HAIKU
#include <stdarg.h>
#endif
@@ -33,17 +35,6 @@ void verb (const char *fmt, ...);
void verb_debug (const char *fmt, ...);
extern void logat (int isverbose, const char *fmt, ...);
-#ifdef NDEBUG
-# define _SUPPORT_DEBUG 0
-#else
-# define _SUPPORT_DEBUG 1
-#endif
-
-#define debug(fmt, ...) do { \
- if (_SUPPORT_DEBUG) \
- logat(1, fmt, ## __VA_ARGS__); \
-} while (0)
-
#define info(fmt, ...) logat(1, fmt, ## __VA_ARGS__)
#define pinfo(fmt, ...) logat(1, fmt ": %s", ## __VA_ARGS__, strerror(errno))
#define error(fmt, ...) logat(0, fmt, ## __VA_ARGS__)
@@ -66,23 +57,25 @@ struct state;
enum event_id_t;
void trigger_event (struct state *state, enum event_id_t e, int sec);
-/* like wait(), but with a timeout. Returns ordinary fork() error codes, or
- * ETIMEDOUT. */
-pid_t wait_with_timeout(int *status, int timeout_secs);
-
struct platform {
- void *(*rtc_open)(void);
- int (*rtc_write)(void *handle, const struct timeval *tv);
- int (*rtc_read)(void *handle, struct timeval *tv);
- int (*rtc_close)(void *handle);
+ int (*rtc_open)(struct rtc_handle *);
+ int (*rtc_write)(struct rtc_handle *, const struct timeval *tv);
+ int (*rtc_read)(struct rtc_handle *, struct timeval *tv);
+ int (*rtc_close)(struct rtc_handle *);
- int (*file_write)(const char *path, void *buf, size_t sz);
- int (*file_read)(const char *path, void *buf, size_t sz);
+ int (*file_open)(const char *path, int write, int cloexec);
+ int (*file_close)(int fd);
+ /* Atomic file write and read */
+ int (*file_write)(int fd, void *buf, size_t sz);
+ int (*file_read)(int fd, void *buf, size_t sz);
int (*time_get)(struct timeval *tv);
int (*pgrp_enter)(void);
int (*pgrp_kill)(void);
+
+ int (*process_signal)(pid_t pid, int sig);
+ int (*process_wait)(pid_t pid, int *status, int timeout);
};
extern struct platform *platform;
diff --git a/tests/run-idle/runs b/tests/run-idle/runs
index 7f8f011..d00491f 100644
--- a/tests/run-idle/runs
+++ b/tests/run-idle/runs
@@ -1 +1 @@
-7
+1
diff --git a/tests/run-routeup/runs b/tests/run-routeup/runs
index d00491f..0cfbf08 100644
--- a/tests/run-routeup/runs
+++ b/tests/run-routeup/runs
@@ -1 +1 @@
-1
+2