]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/clock-util.c
io.systemd.Unit.List fix context/runtime split (#38172)
[thirdparty/systemd.git] / src / shared / clock-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
bbc98d32 2
07630cea 3#include <stdio.h>
bbc98d32 4#include <sys/time.h>
bbc98d32 5
6d3db278 6#include "alloc-util.h"
3ffd4af2
LP
7#include "clock-util.h"
8#include "fd-util.h"
6d3db278 9#include "fileio.h"
07630cea 10#include "string-util.h"
69a283c5 11#include "time-util.h"
bbc98d32 12
18c59794 13int clock_is_localtime(const char *adjtime_path) {
6d3db278 14 int r;
bbc98d32 15
234519ae 16 if (!adjtime_path)
6369641d
MP
17 adjtime_path = "/etc/adjtime";
18
bbc98d32
KS
19 /*
20 * The third line of adjtime is "UTC" or "LOCAL" or nothing.
21 * # /etc/adjtime
22 * 0.0 0 0
23 * 0
24 * UTC
25 */
18c59794
ZJS
26 _cleanup_fclose_ FILE *f = fopen(adjtime_path, "re");
27 if (!f) {
28 if (errno != ENOENT)
29 return -errno;
30
31 /* adjtime_path not present → default to UTC */
32 return false;
33 }
34
35 _cleanup_free_ char *line = NULL;
36 for (unsigned i = 0; i < 2; i++) { /* skip the first two lines */
37 r = read_line(f, LONG_LINE_MAX, NULL);
6d3db278
LP
38 if (r < 0)
39 return r;
40 if (r == 0)
41 return false; /* less than three lines → default to UTC */
18c59794 42 }
bbc98d32 43
18c59794
ZJS
44 r = read_line(f, LONG_LINE_MAX, &line);
45 if (r < 0)
46 return r;
47 if (r == 0)
48 return false; /* less than three lines → default to UTC */
bbc98d32 49
18c59794 50 return streq(line, "LOCAL");
bbc98d32
KS
51}
52
505061bb 53int clock_set_timezone(int *ret_minutesdelta) {
e0f691e1 54 struct tm tm;
6f5cf415
LP
55 int r;
56
57 r = localtime_or_gmtime_usec(now(CLOCK_REALTIME), /* utc= */ false, &tm);
58 if (r < 0)
59 return r;
bbc98d32 60
18c59794 61 int minutesdelta = tm.tm_gmtoff / 60;
bbc98d32 62
18c59794 63 struct timezone tz = {
505061bb
LP
64 .tz_minuteswest = -minutesdelta,
65 .tz_dsttime = 0, /* DST_NONE */
66 };
bbc98d32 67
505061bb
LP
68 /* If the RTC does not run in UTC but in local time, the very first call to settimeofday() will set
69 * the kernel's timezone and will warp the system clock, so that it runs in UTC instead of the local
70 * time we have read from the RTC. */
71 if (settimeofday(NULL, &tz) < 0)
72 return -errno;
73
74 if (ret_minutesdelta)
75 *ret_minutesdelta = minutesdelta;
9c4615fb 76
bbc98d32
KS
77 return 0;
78}