1 /*
2  * save.c - send new time to the time setter
3  * Copyright (c) 2013 The Chromium Authors. All rights reserved.
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "config.h"
9 
10 #include <errno.h>
11 #include <string.h>
12 #include <sys/time.h>
13 #include <unistd.h>
14 
15 #include <event2/event.h>
16 
17 #include "src/conf.h"
18 #include "src/util.h"
19 #include "src/tlsdate.h"
20 
action_sync_and_save(evutil_socket_t fd,short what,void * arg)21 void action_sync_and_save (evutil_socket_t fd, short what, void *arg)
22 {
23   struct state *state = arg;
24   time_t t = state->last_time;
25   ssize_t bytes;
26   verb_debug ("[event:%s] fired", __func__);
27   /* For all non-net sources, don't write to disk by
28    * flagging the time negative.  We don't use negative
29    * times and this won't effect shutdown (0) writes.
30    */
31   if (state->last_sync_type != SYNC_TYPE_NET)
32     t = -t;
33   if (what & EV_READ)
34     {
35       /* EPIPE/EBADF notification */
36       error ("[event:%s] time setter is gone!", __func__);
37       /* SIGCHLD will handle teardown. */
38       return;
39     }
40   bytes = IGNORE_EINTR (write (fd, &t, sizeof (t)));
41   if (bytes == -1)
42     {
43       if (errno == EPIPE)
44         {
45           error ("[event:%s] time setter is gone! (EPIPE)", __func__);
46           return;
47         }
48       if (errno == EAGAIN)
49         return; /* Get notified again. */
50       error ("[event:%s] Unexpected errno %d", __func__, errno);
51     }
52   if (bytes != sizeof (t))
53     pfatal ("[event:%s] unexpected write to time setter (%d)",
54             __func__, bytes);
55   /* If we're going down and we wrote the time, send a shutdown message. */
56   if (state->exitting && t)
57     {
58       state->last_time = 0;
59       action_sync_and_save (fd, what, arg);
60       /* TODO(wad) platform->pgrp_kill() ? */
61     }
62   return;
63 }
64