From 78beadd60b81c0b3c92eca38890983a672dbfd93 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 10 Jul 2015 01:21:28 -0500 Subject: Promote hwclock. --- toys/other/hwclock.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ toys/pending/hwclock.c | 136 ------------------------------------------------- 2 files changed, 136 insertions(+), 136 deletions(-) create mode 100644 toys/other/hwclock.c delete mode 100644 toys/pending/hwclock.c diff --git a/toys/other/hwclock.c b/toys/other/hwclock.c new file mode 100644 index 00000000..75e06416 --- /dev/null +++ b/toys/other/hwclock.c @@ -0,0 +1,136 @@ +/* hwclock.c - get and set the hwclock + * + * Copyright 2014 Bilal Qureshi + * + * No standard, but see Documentation/rtc.txt in the linux kernel source.. + * +USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_USR|TOYFLAG_BIN)) + +config HWCLOCK + bool "hwclock" + default y + help + usage: hwclock [-rswtluf] + + -f FILE Use specified device file instead of /dev/rtc (--rtc) + -l Hardware clock uses localtime (--localtime) + -r Show hardware clock time (--show) + -s Set system time from hardware clock (--hctosys) + -t Set the system time based on the current timezone (--systz) + -u Hardware clock uses UTC (--utc) + -w Set hardware clock from system time (--systohc) +*/ + +#define FOR_hwclock +#include "toys.h" +#include + +GLOBALS( + char *fname; + + int utc; +) + +static int rtc_find(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, 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; +} + +void hwclock_main() +{ + struct timezone tzone; + struct timeval timeval; + struct tm tm; + time_t time; + int fd = -1; + + // check for Grenich Mean Time + if (toys.optflags & FLAG_u) TT.utc = 1; + else { + FILE *fp; + char *s = 0; + + for (fp = fopen("/etc/adjtime", "r"); + fp && getline(&s, (void *)toybuf, fp)>0; + free(s), s = 0) TT.utc += !strncmp(s, "UTC", 3); + if (fp) fclose(fp); + } + + if (!(toys.optflags&FLAG_t)) { + int w = toys.optflags & FLAG_w, flag = O_WRONLY*w; + + // Open /dev/rtc (if your system has no /dev/rtc symlink, search for it). + if (!TT.fname && (fd = open("/dev/rtc", flag)) == -1) { + dirtree_read("/sys/class/rtc", rtc_find); + if (!TT.fname) TT.fname = "/dev/misc/rtc"; + } + if (fd == -1) fd = xopen(TT.fname, flag); + + // Get current time in seconds from rtc device. todo: get subsecond time + if (!w) { + char *s = s; + + xioctl(fd, RTC_RD_TIME, &tm); + if (TT.utc) s = xtzset("UTC0"); + if ((time = mktime(&tm)) < 0) error_exit("mktime failed"); + if (TT.utc) { + free(xtzset(s)); + free(s); + } + } + } + + if (toys.optflags & (FLAG_w|FLAG_t)) { + if (gettimeofday(&timeval, 0)) perror_exit("gettimeofday failed"); + if (!(TT.utc ? gmtime_r : localtime_r)(&timeval.tv_sec, &tm)) + error_exit(TT.utc ? "gmtime_r failed" : "localtime_r failed"); + } + + if (toys.optflags & FLAG_w) { + /* The value of tm_isdst will positive if daylight saving time is in effect, + * zero if it is not and negative if the information is not available. + * todo: so why isn't this negative...? */ + tm.tm_isdst = 0; + xioctl(fd, RTC_SET_TIME, &tm); + } else if (toys.optflags & FLAG_s) { + tzone.tz_minuteswest = timezone / 60 - 60 * daylight; + timeval.tv_sec = time; + timeval.tv_usec = 0; // todo: fixit + } else if (toys.optflags & FLAG_t) { + // Adjust seconds for timezone and daylight saving time + // extern long timezone is defined in header sys/time.h + tzone.tz_minuteswest = timezone / 60; + if (tm.tm_isdst) tzone.tz_minuteswest -= 60; + if (!TT.utc) timeval.tv_sec += tzone.tz_minuteswest * 60; + } else { + char *c = ctime(&time), *s = strrchr(c, '\n'); + + if (s) *s = '\0'; + // TODO: implement this. + xprintf("%s 0.000000 seconds\n", c); + } + if (toys.optflags & (FLAG_t|FLAG_s)) { + tzone.tz_dsttime = 0; + if (settimeofday(&timeval, &tzone)) perror_exit("settimeofday failed"); + } + + if (fd != -1) close(fd); +} diff --git a/toys/pending/hwclock.c b/toys/pending/hwclock.c deleted file mode 100644 index d87266af..00000000 --- a/toys/pending/hwclock.c +++ /dev/null @@ -1,136 +0,0 @@ -/* hwclock.c - get and set the hwclock - * - * Copyright 2014 Bilal Qureshi - * - * No standard, but see Documentation/rtc.txt in the linux kernel source.. - * -USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_USR|TOYFLAG_BIN)) - -config HWCLOCK - bool "hwclock" - default n - help - usage: hwclock [-rswtluf] - - -f FILE Use specified device file instead of /dev/rtc (--rtc) - -l Hardware clock uses localtime (--localtime) - -r Show hardware clock time (--show) - -s Set system time from hardware clock (--hctosys) - -t Set the system time based on the current timezone (--systz) - -u Hardware clock uses UTC (--utc) - -w Set hardware clock from system time (--systohc) -*/ - -#define FOR_hwclock -#include "toys.h" -#include - -GLOBALS( - char *fname; - - int utc; -) - -static int rtc_find(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, 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; -} - -void hwclock_main() -{ - struct timezone tzone; - struct timeval timeval; - struct tm tm; - time_t time; - int fd = -1; - - // check for Grenich Mean Time - if (toys.optflags & FLAG_u) TT.utc = 1; - else { - FILE *fp; - char *s = 0; - - for (fp = fopen("/etc/adjtime", "r"); - fp && getline(&s, (void *)toybuf, fp)>0; - free(s), s = 0) TT.utc += !strncmp(s, "UTC", 3); - if (fp) fclose(fp); - } - - if (!(toys.optflags&FLAG_t)) { - int w = toys.optflags & FLAG_w, flag = O_WRONLY*w; - - // Open /dev/rtc (if your system has no /dev/rtc symlink, search for it). - if (!TT.fname && (fd = open("/dev/rtc", flag)) == -1) { - dirtree_read("/sys/class/rtc", rtc_find); - if (!TT.fname) TT.fname = "/dev/misc/rtc"; - } - if (fd == -1) fd = xopen(TT.fname, flag); - - // Get current time in seconds from rtc device. todo: get subsecond time - if (!w) { - char *s = s; - - xioctl(fd, RTC_RD_TIME, &tm); - if (TT.utc) s = xtzset("UTC0"); - if ((time = mktime(&tm)) < 0) error_exit("mktime failed"); - if (TT.utc) { - free(xtzset(s)); - free(s); - } - } - } - - if (toys.optflags & (FLAG_w|FLAG_t)) { - if (gettimeofday(&timeval, 0)) perror_exit("gettimeofday failed"); - if (!(TT.utc ? gmtime_r : localtime_r)(&timeval.tv_sec, &tm)) - error_exit(TT.utc ? "gmtime_r failed" : "localtime_r failed"); - } - - if (toys.optflags & FLAG_w) { - /* The value of tm_isdst will positive if daylight saving time is in effect, - * zero if it is not and negative if the information is not available. - * todo: so why isn't this negative...? */ - tm.tm_isdst = 0; - xioctl(fd, RTC_SET_TIME, &tm); - } else if (toys.optflags & FLAG_s) { - tzone.tz_minuteswest = timezone / 60 - 60 * daylight; - timeval.tv_sec = time; - timeval.tv_usec = 0; // todo: fixit - } else if (toys.optflags & FLAG_t) { - // Adjust seconds for timezone and daylight saving time - // extern long timezone is defined in header sys/time.h - tzone.tz_minuteswest = timezone / 60; - if (tm.tm_isdst) tzone.tz_minuteswest -= 60; - if (!TT.utc) timeval.tv_sec += tzone.tz_minuteswest * 60; - } else { - char *c = ctime(&time), *s = strrchr(c, '\n'); - - if (s) *s = '\0'; - // TODO: implement this. - xprintf("%s 0.000000 seconds\n", c); - } - if (toys.optflags & (FLAG_t|FLAG_s)) { - tzone.tz_dsttime = 0; - if (settimeofday(&timeval, &tzone)) perror_exit("settimeofday failed"); - } - - if (fd != -1) close(fd); -} -- cgit v1.2.3