]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/clock-util.c
Merge pull request #8575 from keszybz/non-absolute-paths
[thirdparty/systemd.git] / src / basic / clock-util.c
index e4e03df1e47d196f1457e8c2ea00689de0780afb..5ef76d46f2094a53c7e51d49f39fa92e3a2e232a 100644 (file)
@@ -1,34 +1,25 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   Copyright 2010-2012 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
 #include <errno.h>
-#include <stdio.h>
 #include <fcntl.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <time.h>
+#include <linux/rtc.h>
+#include <stdio.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
-#include <linux/rtc.h>
 
+#include "clock-util.h"
+#include "fd-util.h"
 #include "macro.h"
+#include "string-util.h"
 #include "util.h"
-#include "clock-util.h"
 
 int clock_get_hwclock(struct tm *tm) {
         _cleanup_close_ int fd = -1;
@@ -66,9 +57,12 @@ int clock_set_hwclock(const struct tm *tm) {
         return 0;
 }
 
-int clock_is_localtime(void) {
+int clock_is_localtime(const char* adjtime_path) {
         _cleanup_fclose_ FILE *f;
 
+        if (!adjtime_path)
+                adjtime_path = "/etc/adjtime";
+
         /*
          * The third line of adjtime is "UTC" or "LOCAL" or nothing.
          *   # /etc/adjtime
@@ -76,7 +70,7 @@ int clock_is_localtime(void) {
          *   0
          *   UTC
          */
-        f = fopen("/etc/adjtime", "re");
+        f = fopen(adjtime_path, "re");
         if (f) {
                 char line[LINE_MAX];
                 bool b;
@@ -85,7 +79,8 @@ int clock_is_localtime(void) {
                         fgets(line, sizeof(line), f) &&
                         fgets(line, sizeof(line), f);
                 if (!b)
-                        return -EIO;
+                        /* less than three lines -> default to UTC */
+                        return 0;
 
                 truncate_nl(line);
                 return streq(line, "LOCAL");
@@ -93,6 +88,7 @@ int clock_is_localtime(void) {
         } else if (errno != ENOENT)
                 return -errno;
 
+        /* adjtime not present -> default to UTC */
         return 0;
 }
 
@@ -117,7 +113,8 @@ int clock_set_timezone(int *min) {
          * have read from the RTC.
          */
         if (settimeofday(tv_null, &tz) < 0)
-                return -errno;
+                return negative_errno();
+
         if (min)
                 *min = minutesdelta;
         return 0;
@@ -140,3 +137,17 @@ int clock_reset_timewarp(void) {
 
         return 0;
 }
+
+#define TIME_EPOCH_USEC ((usec_t) TIME_EPOCH * USEC_PER_SEC)
+
+int clock_apply_epoch(void) {
+        struct timespec ts;
+
+        if (now(CLOCK_REALTIME) >= TIME_EPOCH_USEC)
+                return 0;
+
+        if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, TIME_EPOCH_USEC)) < 0)
+                return -errno;
+
+        return 1;
+}