diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-06 22:43:39 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-06 22:43:39 +0100 |
commit | 5e3b14069e3fe25ec2595124e6e0103c7be4f813 (patch) | |
tree | d818305a88168d4aff500e2dc9a5fb590763375a | |
parent | 695fa51c80047eb25cc82e6e1630b4545a6bc0b6 (diff) | |
download | busybox-w32-5e3b14069e3fe25ec2595124e6e0103c7be4f813.tar.gz busybox-w32-5e3b14069e3fe25ec2595124e6e0103c7be4f813.tar.bz2 busybox-w32-5e3b14069e3fe25ec2595124e6e0103c7be4f813.zip |
hwclock: make it report system/rtc clock difference
function old new delta
rtc_tm2time - 89 +89
read_rtc 23 86 +63
rtc_read_tm - 49 +49
hwclock_main 428 466 +38
rtcwake_main 453 477 +24
rtc_read_time 142 - -142
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 3/0 up/down: 263/-142) Total: 121 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/rtc_.h | 8 | ||||
-rw-r--r-- | libbb/rtc.c | 18 | ||||
-rw-r--r-- | util-linux/hwclock.c | 44 | ||||
-rw-r--r-- | util-linux/rtcwake.c | 7 |
4 files changed, 53 insertions, 24 deletions
diff --git a/include/rtc_.h b/include/rtc_.h index 74bb695a0..2b4ae778d 100644 --- a/include/rtc_.h +++ b/include/rtc_.h | |||
@@ -11,9 +11,11 @@ | |||
11 | 11 | ||
12 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | 12 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN |
13 | 13 | ||
14 | extern int rtc_adjtime_is_utc(void) FAST_FUNC; | 14 | int rtc_adjtime_is_utc(void) FAST_FUNC; |
15 | extern int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; | 15 | int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; |
16 | extern time_t rtc_read_time(int fd, int utc) FAST_FUNC; | 16 | void rtc_read_tm(struct tm *tm, int fd) FAST_FUNC; |
17 | time_t rtc_tm2time(struct tm *tm, int utc) FAST_FUNC; | ||
18 | |||
17 | 19 | ||
18 | /* | 20 | /* |
19 | * Everything below this point has been copied from linux/rtc.h | 21 | * Everything below this point has been copied from linux/rtc.h |
diff --git a/libbb/rtc.c b/libbb/rtc.c index 2f38b8a7e..9807e1cf9 100644 --- a/libbb/rtc.c +++ b/libbb/rtc.c | |||
@@ -59,15 +59,17 @@ int FAST_FUNC rtc_xopen(const char **default_rtc, int flags) | |||
59 | return xopen(*default_rtc, flags); | 59 | return xopen(*default_rtc, flags); |
60 | } | 60 | } |
61 | 61 | ||
62 | time_t FAST_FUNC rtc_read_time(int fd, int utc) | 62 | void FAST_FUNC rtc_read_tm(struct tm *tm, int fd) |
63 | { | 63 | { |
64 | struct tm tm; | 64 | memset(tm, 0, sizeof(*tm)); |
65 | char *oldtz = 0; | 65 | xioctl(fd, RTC_RD_TIME, tm); |
66 | time_t t = 0; | 66 | tm->tm_isdst = -1; /* "not known" */ |
67 | } | ||
67 | 68 | ||
68 | memset(&tm, 0, sizeof(struct tm)); | 69 | time_t FAST_FUNC rtc_tm2time(struct tm *tm, int utc) |
69 | xioctl(fd, RTC_RD_TIME, &tm); | 70 | { |
70 | tm.tm_isdst = -1; /* not known */ | 71 | char *oldtz = oldtz; /* for compiler */ |
72 | time_t t; | ||
71 | 73 | ||
72 | if (utc) { | 74 | if (utc) { |
73 | oldtz = getenv("TZ"); | 75 | oldtz = getenv("TZ"); |
@@ -75,7 +77,7 @@ time_t FAST_FUNC rtc_read_time(int fd, int utc) | |||
75 | tzset(); | 77 | tzset(); |
76 | } | 78 | } |
77 | 79 | ||
78 | t = mktime(&tm); | 80 | t = mktime(tm); |
79 | 81 | ||
80 | if (utc) { | 82 | if (utc) { |
81 | unsetenv("TZ"); | 83 | unsetenv("TZ"); |
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 08e5bd701..606721e2c 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -20,34 +20,54 @@ | |||
20 | 20 | ||
21 | static const char *rtcname; | 21 | static const char *rtcname; |
22 | 22 | ||
23 | static time_t read_rtc(int utc) | 23 | static time_t read_rtc(struct timeval *sys_tv, int utc) |
24 | { | 24 | { |
25 | time_t ret; | 25 | struct tm tm; |
26 | int fd; | 26 | int fd; |
27 | int before; | ||
27 | 28 | ||
28 | fd = rtc_xopen(&rtcname, O_RDONLY); | 29 | fd = rtc_xopen(&rtcname, O_RDONLY); |
29 | ret = rtc_read_time(fd, utc); | 30 | |
31 | rtc_read_tm(&tm, fd); | ||
32 | before = tm.tm_sec; | ||
33 | while (1) { | ||
34 | rtc_read_tm(&tm, fd); | ||
35 | gettimeofday(sys_tv, NULL); | ||
36 | if (before != tm.tm_sec) | ||
37 | break; | ||
38 | } | ||
39 | |||
30 | if (ENABLE_FEATURE_CLEAN_UP) | 40 | if (ENABLE_FEATURE_CLEAN_UP) |
31 | close(fd); | 41 | close(fd); |
32 | 42 | ||
33 | return ret; | 43 | return rtc_tm2time(&tm, utc); |
34 | } | 44 | } |
35 | 45 | ||
36 | static void show_clock(int utc) | 46 | static void show_clock(int utc) |
37 | { | 47 | { |
38 | //struct tm *ptm; | 48 | struct timeval sys_tv; |
39 | time_t t; | 49 | time_t t; |
50 | long diff; | ||
40 | char *cp; | 51 | char *cp; |
41 | 52 | ||
42 | t = read_rtc(utc); | 53 | t = read_rtc(&sys_tv, utc); |
43 | //ptm = localtime(&t); /* Sets 'tzname[]' */ | ||
44 | 54 | ||
45 | cp = ctime(&t); | 55 | cp = ctime(&t); |
46 | strchrnul(cp, '\n')[0] = '\0'; | 56 | strchrnul(cp, '\n')[0] = '\0'; |
47 | 57 | ||
48 | //printf("%s 0.000000 seconds %s\n", cp, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); | 58 | //printf("%s 0.000000 seconds %s\n", cp, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); |
49 | /* 0.000000 stand for unimplemented difference between RTC and system clock */ | 59 | diff = sys_tv.tv_sec - t; |
50 | printf("%s 0.000000 seconds\n", cp); | 60 | if (diff < 0 /*&& tv.tv_usec != 0*/) { |
61 | /* Why? */ | ||
62 | /* diff >= 0 is ok: diff < 0, can't just use tv.tv_usec: */ | ||
63 | /* 45.520820 43.520820 */ | ||
64 | /* - 44.000000 - 45.000000 */ | ||
65 | /* = 0.520820 = -1.479180, not -2.520820! */ | ||
66 | diff++; | ||
67 | /* should be 1000000 - tv.tv_usec, but then we must check tv.tv_usec != 0 */ | ||
68 | sys_tv.tv_usec = 999999 - sys_tv.tv_usec; | ||
69 | } | ||
70 | printf("%s %ld.%06lu seconds\n", cp, diff, (unsigned long)sys_tv.tv_usec); | ||
51 | } | 71 | } |
52 | 72 | ||
53 | static void to_sys_clock(int utc) | 73 | static void to_sys_clock(int utc) |
@@ -58,7 +78,7 @@ static void to_sys_clock(int utc) | |||
58 | tz.tz_minuteswest = timezone/60 - 60*daylight; | 78 | tz.tz_minuteswest = timezone/60 - 60*daylight; |
59 | tz.tz_dsttime = 0; | 79 | tz.tz_dsttime = 0; |
60 | 80 | ||
61 | tv.tv_sec = read_rtc(utc); | 81 | tv.tv_sec = read_rtc(NULL, utc); |
62 | tv.tv_usec = 0; | 82 | tv.tv_usec = 0; |
63 | if (settimeofday(&tv, &tz)) | 83 | if (settimeofday(&tv, &tz)) |
64 | bb_perror_msg_and_die("settimeofday() failed"); | 84 | bb_perror_msg_and_die("settimeofday() failed"); |
@@ -79,15 +99,15 @@ static void from_sys_clock(int utc) | |||
79 | 99 | ||
80 | gettimeofday(&tv, NULL); | 100 | gettimeofday(&tv, NULL); |
81 | 101 | ||
102 | t = tv.tv_sec; | ||
82 | rem_usec = 1000000 - tv.tv_usec; | 103 | rem_usec = 1000000 - tv.tv_usec; |
83 | if (rem_usec < 1024) { | 104 | if (rem_usec < 1024) { |
84 | /* Less than 1ms to next second. Good enough */ | 105 | /* Less than 1ms to next second. Good enough */ |
85 | small_rem: | 106 | small_rem: |
86 | tv.tv_sec++; | 107 | t++; |
87 | } | 108 | } |
88 | 109 | ||
89 | /* Prepare tm */ | 110 | /* Prepare tm */ |
90 | t = tv.tv_sec; | ||
91 | if (utc) | 111 | if (utc) |
92 | gmtime_r(&t, &tm); /* may read /etc/xxx (it takes time) */ | 112 | gmtime_r(&t, &tm); /* may read /etc/xxx (it takes time) */ |
93 | else | 113 | else |
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c index 049f699f5..64c3e7ed7 100644 --- a/util-linux/rtcwake.c +++ b/util-linux/rtcwake.c | |||
@@ -160,7 +160,12 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv) | |||
160 | 160 | ||
161 | /* relative or absolute alarm time, normalized to time_t */ | 161 | /* relative or absolute alarm time, normalized to time_t */ |
162 | sys_time = time(NULL); | 162 | sys_time = time(NULL); |
163 | rtc_time = rtc_read_time(fd, utc); | 163 | { |
164 | struct tm tm; | ||
165 | rtc_read_tm(&tm, fd); | ||
166 | rtc_time = rtc_tm2time(&tm, utc); | ||
167 | } | ||
168 | |||
164 | 169 | ||
165 | if (alarm_time) { | 170 | if (alarm_time) { |
166 | if (alarm_time < sys_time) | 171 | if (alarm_time < sys_time) |