]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/clock-util.c
journald: correct spacing near eol code comments
[thirdparty/systemd.git] / src / shared / clock-util.c
CommitLineData
bbc98d32
KS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010-2012 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <assert.h>
23#include <string.h>
24#include <unistd.h>
25#include <errno.h>
26#include <stdlib.h>
27#include <signal.h>
28#include <stdio.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <sys/ioctl.h>
33#include <stdarg.h>
34#include <ctype.h>
35#include <sys/prctl.h>
36#include <sys/time.h>
37#include <linux/rtc.h>
38
39#include "macro.h"
40#include "util.h"
41#include "log.h"
42#include "strv.h"
24efb112 43#include "clock-util.h"
a5c32cff 44#include "fileio.h"
bbc98d32 45
60989612 46int clock_get_hwclock(struct tm *tm) {
8e64fd11 47 _cleanup_close_ int fd = -1;
bbc98d32
KS
48
49 assert(tm);
50
67fb4482 51 fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
bbc98d32
KS
52 if (fd < 0)
53 return -errno;
54
55 /* This leaves the timezone fields of struct tm
56 * uninitialized! */
57 if (ioctl(fd, RTC_RD_TIME, tm) < 0)
8e64fd11 58 return -errno;
bbc98d32
KS
59
60 /* We don't know daylight saving, so we reset this in order not
2f6a5907 61 * to confuse mktime(). */
bbc98d32
KS
62 tm->tm_isdst = -1;
63
8e64fd11 64 return 0;
bbc98d32
KS
65}
66
60989612 67int clock_set_hwclock(const struct tm *tm) {
8e64fd11 68 _cleanup_close_ int fd = -1;
bbc98d32
KS
69
70 assert(tm);
71
67fb4482 72 fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
bbc98d32
KS
73 if (fd < 0)
74 return -errno;
75
76 if (ioctl(fd, RTC_SET_TIME, tm) < 0)
8e64fd11 77 return -errno;
bbc98d32 78
8e64fd11 79 return 0;
bbc98d32 80}
a866073d 81
24efb112 82int clock_is_localtime(void) {
7fd1b19b 83 _cleanup_fclose_ FILE *f;
bbc98d32
KS
84
85 /*
86 * The third line of adjtime is "UTC" or "LOCAL" or nothing.
87 * # /etc/adjtime
88 * 0.0 0 0
89 * 0
90 * UTC
91 */
92 f = fopen("/etc/adjtime", "re");
93 if (f) {
94 char line[LINE_MAX];
95 bool b;
96
97 b = fgets(line, sizeof(line), f) &&
98 fgets(line, sizeof(line), f) &&
99 fgets(line, sizeof(line), f);
bbc98d32
KS
100 if (!b)
101 return -EIO;
102
103 truncate_nl(line);
8e2f9ebf 104 return streq(line, "LOCAL");
bbc98d32 105
bcb161b0 106 } else if (errno != ENOENT)
bbc98d32
KS
107 return -errno;
108
8e2f9ebf 109 return 0;
bbc98d32
KS
110}
111
24efb112 112int clock_set_timezone(int *min) {
bbc98d32
KS
113 const struct timeval *tv_null = NULL;
114 struct timespec ts;
115 struct tm *tm;
19e65613 116 int minutesdelta;
bbc98d32
KS
117 struct timezone tz;
118
119 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
120 assert_se(tm = localtime(&ts.tv_sec));
19e65613 121 minutesdelta = tm->tm_gmtoff / 60;
bbc98d32 122
19e65613 123 tz.tz_minuteswest = -minutesdelta;
bbc98d32
KS
124 tz.tz_dsttime = 0; /* DST_NONE*/
125
126 /*
c264aeab
KS
127 * If the RTC does not run in UTC but in local time, the very first
128 * call to settimeofday() will set the kernel's timezone and will warp the
129 * system clock, so that it runs in UTC instead of the local time we
130 * have read from the RTC.
bbc98d32
KS
131 */
132 if (settimeofday(tv_null, &tz) < 0)
133 return -errno;
134 if (min)
19e65613 135 *min = minutesdelta;
bbc98d32
KS
136 return 0;
137}
138
c264aeab 139int clock_reset_timewarp(void) {
bbc98d32
KS
140 const struct timeval *tv_null = NULL;
141 struct timezone tz;
142
143 tz.tz_minuteswest = 0;
144 tz.tz_dsttime = 0; /* DST_NONE*/
145
72edcff5 146 /*
c264aeab
KS
147 * The very first call to settimeofday() does time warp magic. Do a
148 * dummy call here, so the time warping is sealed and all later calls
149 * behave as expected.
72edcff5 150 */
bbc98d32
KS
151 if (settimeofday(tv_null, &tz) < 0)
152 return -errno;
153
154 return 0;
155}