#include "log.h"
#include "strv.h"
#include "hwclock.h"
-
-static int rtc_open(int flags) {
- int fd;
- DIR *d;
-
- /* First, we try to make use of the /dev/rtc symlink. If that
- * doesn't exist, we open the first RTC which has hctosys=1
- * set. If we don't find any we just take the first RTC that
- * exists at all. */
-
- fd = open("/dev/rtc", flags);
- if (fd >= 0)
- return fd;
-
- 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 = strjoin("/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;
-}
+#include "fileio.h"
int hwclock_get_time(struct tm *tm) {
- int fd;
- int err = 0;
+ _cleanup_close_ int fd = -1;
assert(tm);
- fd = rtc_open(O_RDONLY|O_CLOEXEC);
+ fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
/* This leaves the timezone fields of struct tm
* uninitialized! */
if (ioctl(fd, RTC_RD_TIME, tm) < 0)
- err = -errno;
+ return -errno;
/* We don't know daylight saving, so we reset this in order not
- * to confused mktime(). */
+ * to confuse mktime(). */
tm->tm_isdst = -1;
- close_nointr_nofail(fd);
-
- return err;
+ return 0;
}
int hwclock_set_time(const struct tm *tm) {
- int fd;
- int err = 0;
+ _cleanup_close_ int fd = -1;
assert(tm);
- fd = rtc_open(O_RDONLY|O_CLOEXEC);
+ fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
if (ioctl(fd, RTC_SET_TIME, tm) < 0)
- err = -errno;
-
- close_nointr_nofail(fd);
+ return -errno;
- return err;
+ return 0;
}
+
int hwclock_is_localtime(void) {
- FILE *f;
- bool local = false;
+ _cleanup_fclose_ FILE *f;
/*
* The third line of adjtime is "UTC" or "LOCAL" or nothing.
b = fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f);
-
- fclose(f);
-
if (!b)
return -EIO;
truncate_nl(line);
- local = streq(line, "LOCAL");
+ return streq(line, "LOCAL");
- } else if (errno != -ENOENT)
+ } else if (errno != ENOENT)
return -errno;
- return local;
+ return 0;
}
int hwclock_set_timezone(int *min) {
const struct timeval *tv_null = NULL;
struct timespec ts;
struct tm *tm;
- int minuteswest;
+ int minutesdelta;
struct timezone tz;
assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
assert_se(tm = localtime(&ts.tv_sec));
- minuteswest = tm->tm_gmtoff / 60;
+ minutesdelta = tm->tm_gmtoff / 60;
- tz.tz_minuteswest = -minuteswest;
+ tz.tz_minuteswest = -minutesdelta;
tz.tz_dsttime = 0; /* DST_NONE*/
/*
if (settimeofday(tv_null, &tz) < 0)
return -errno;
if (min)
- *min = minuteswest;
+ *min = minutesdelta;
return 0;
}
/*
* The very first time we set the kernel's timezone, it will warp
* the clock. Do a dummy call here, so the time warping is sealed
- * and we set only the time zone with next call.
+ * and we set only the timezone with next call.
*/
if (settimeofday(tv_null, &tz) < 0)
return -errno;