[systemd-commits] TODO src/util.c src/util.h

Lennart Poettering lennart at kemper.freedesktop.org
Fri Jan 20 18:16:42 PST 2012


 TODO       |    2 -
 src/util.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/util.h |    2 +
 3 files changed, 69 insertions(+), 4 deletions(-)

New commits:
commit 51122dc9e36cdafe76a07d1ddf1a3a7e4726bb7b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jan 21 03:15:54 2012 +0100

    util: open the first RTC that has hctosys=1 set

diff --git a/TODO b/TODO
index 2c7e2b0..3b4d45f 100644
--- a/TODO
+++ b/TODO
@@ -23,8 +23,6 @@ Features:
 
 * document the exit codes when services fail before they are exec()ed
 
-* use the rtc which has: /sys/class/rtc/*/hctosys == "1" as the system RTC
-
 * rework namespace support, don't use pivot_root, and mount things after creating the namespace, not before
 
 * systemctl journal command
diff --git a/src/util.c b/src/util.c
index fbc37c4..de5feeb 100644
--- a/src/util.c
+++ b/src/util.c
@@ -5155,13 +5155,78 @@ int hwclock_reset_localtime_delta(void) {
         return 0;
 }
 
+int rtc_open(int flags) {
+        int fd;
+        DIR *d;
+
+        /* We open the first RTC which has hctosys=1 set. If we don't
+         * find any we just take the first one */
+
+        d = opendir("/sys/class/rtc");
+        if (!d)
+                goto fallback;
+
+        for (;;) {
+                char *p, *v;
+                struct dirent buf, *de;
+                int r;
+
+                r = readdir_r(d, &buf, &de);
+                if (r != 0)
+                        goto fallback;
+
+                if (!de)
+                        goto fallback;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL);
+                if (!p) {
+                        closedir(d);
+                        return -ENOMEM;
+                }
+
+                r = read_one_line_file(p, &v);
+                free(p);
+
+                if (r < 0)
+                        continue;
+
+                r = parse_boolean(v);
+                free(v);
+
+                if (r <= 0)
+                        continue;
+
+                p = strappend("/dev/", de->d_name);
+                fd = open(p, flags);
+                free(p);
+
+                if (fd >= 0) {
+                        closedir(d);
+                        return fd;
+                }
+        }
+
+fallback:
+        if (d)
+                closedir(d);
+
+        fd = open("/dev/rtc0", flags);
+        if (fd < 0)
+                return -errno;
+
+        return fd;
+}
+
 int hwclock_get_time(struct tm *tm) {
         int fd;
         int err = 0;
 
         assert(tm);
 
-        fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+        fd = rtc_open(O_RDONLY|O_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
@@ -5185,7 +5250,7 @@ int hwclock_set_time(const struct tm *tm) {
 
         assert(tm);
 
-        fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+        fd = rtc_open(O_RDONLY|O_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
diff --git a/src/util.h b/src/util.h
index 6acfcc8..114b24c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -529,4 +529,6 @@ int fd_wait_for_event(int fd, int event);
 
 void* memdup(const void *p, size_t l);
 
+int rtc_open(int flags);
+
 #endif



More information about the systemd-commits mailing list