aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-01-20 16:03:29 -0600
committerElliott Hughes <enh@google.com>2015-01-20 16:03:29 -0600
commitef0546d4f536f42a57af4c32bd37f7fd752d10c2 (patch)
tree943862c91cdeeb926162145ee7c8548b2f1c30da
parent9d1d0ad1236d3c2d85e6c244d148f5ae8f589631 (diff)
downloadtoybox-ef0546d4f536f42a57af4c32bd37f7fd752d10c2.tar.gz
fix hwclock's rtc selection
For systems using /dev/rtcN, /dev/rtc0 isn't necessarily the RTC that's used to provide the system time at boot time. We need to search for the RTC whose /sys/class/rtc/rtcN/hctosys contains "1".
-rw-r--r--toys/pending/hwclock.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/toys/pending/hwclock.c b/toys/pending/hwclock.c
index d943e57a..003174f7 100644
--- a/toys/pending/hwclock.c
+++ b/toys/pending/hwclock.c
@@ -30,13 +30,43 @@ GLOBALS(
int utc;
)
+static int check_hctosys(struct dirtree* node)
+{
+ FILE *fp;
+
+ if (!node->parent) return DIRTREE_RECURSE;
+
+ snprintf(toybuf, sizeof(toybuf), "/sys/class/rtc/%s/hctosys", node->name);
+ fp = fopen(toybuf, "r");
+ if (fp) {
+ int hctosys = 0;
+ int items = fscanf(fp, "%d", &hctosys);
+ fclose(fp);
+ if (items == 1 && hctosys == 1) {
+ snprintf(toybuf, sizeof(toybuf), "/dev/%s", node->name);
+ TT.fname = toybuf;
+ return DIRTREE_ABORT;
+ }
+ }
+ return 0;
+}
+
+// Search /sys/class/rtc for the RTC that the system clock is set from.
+// See the kernel's Documentation/rtc.txt.
+static int open_wall_clock_rtc(int flag)
+{
+ TT.fname = NULL;
+ dirtree_read("/sys/class/rtc", check_hctosys);
+ return TT.fname ? xopen(TT.fname, flag) : -1;
+}
+
static int rtc_open(int flag)
{
if (!TT.fname) {
int fd;
if ((fd = open((TT.fname = "/dev/rtc"), flag)) != -1) return fd;
- else if ((fd = open((TT.fname = "/dev/rtc0"), flag)) != -1) return fd;
+ else if ((fd = open_wall_clock_rtc(flag)) != -1) return fd;
else TT.fname = "/dev/misc/rtc";
}
return xopen(TT.fname, flag);