X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fhwclock.c;h=7059d9c75b8367a0cb1d3b39983d74087cc54f6d;hp=d40bb2653f886b5ef70b70c53d94aaa15d7715b4;hb=1ae383a8a3ae4824453e297352fda603d2d3fd5e;hpb=bbc98d32560cc456531bf254f7b69054921082bd diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index d40bb2653..7059d9c75 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -41,122 +41,46 @@ #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 = 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; -} +#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. @@ -173,33 +97,30 @@ int hwclock_is_localtime(void) { 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_apply_localtime_delta(int *min) { +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*/ /* @@ -210,17 +131,22 @@ int hwclock_apply_localtime_delta(int *min) { if (settimeofday(tv_null, &tz) < 0) return -errno; if (min) - *min = minuteswest; + *min = minutesdelta; return 0; } -int hwclock_reset_localtime_delta(void) { +int hwclock_reset_timezone(void) { const struct timeval *tv_null = NULL; struct timezone tz; tz.tz_minuteswest = 0; tz.tz_dsttime = 0; /* DST_NONE*/ + /* + * 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 timezone with next call. + */ if (settimeofday(tv_null, &tz) < 0) return -errno;