hwclock: implement --systz
authorDavide Cavalca <davide@geexbox.org>
Sat, 22 Jan 2011 17:55:32 +0000 (18:55 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Jan 2011 17:55:32 +0000 (18:55 +0100)
function                                             old     new   delta
hwclock_main                                         324     434    +110
packed_usage                                       28220   28259     +39
static.hwclock_longopts                               53      60      +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 156/0)             Total: 156 bytes

Signed-off-by: Davide Cavalca <davide@geexbox.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/usage.src.h
util-linux/hwclock.c

index 9300b3ce8d051822dab7108444b2e2a4cd0a9b85..ebe80f8e19de504540e15d21df6d8e7ce5b14c31 100644 (file)
@@ -1595,25 +1595,6 @@ INSERT
      "\n       -e STRING       HTML encode STRING" \
      "\n       -d STRING       URL decode STRING" \
 
-#define hwclock_trivial_usage \
-       IF_FEATURE_HWCLOCK_LONG_OPTIONS( \
-       "[-r|--show] [-s|--hctosys] [-w|--systohc]" \
-       " [-l|--localtime] [-u|--utc]" \
-       " [-f FILE]" \
-       ) \
-       IF_NOT_FEATURE_HWCLOCK_LONG_OPTIONS( \
-       "[-r] [-s] [-w] [-l] [-u] [-f FILE]" \
-       )
-#define hwclock_full_usage "\n\n" \
-       "Query and set hardware clock (RTC)\n" \
-     "\nOptions:" \
-     "\n       -r      Show hardware clock time" \
-     "\n       -s      Set system time from hardware clock" \
-     "\n       -w      Set hardware clock to system time" \
-     "\n       -u      Hardware clock is in UTC" \
-     "\n       -l      Hardware clock is in local time" \
-     "\n       -f FILE Use specified device (e.g. /dev/rtc2)" \
-
 #define id_trivial_usage \
        "[OPTIONS] [USER]"
 #define id_full_usage "\n\n" \
index 922dd057885ac2d5b0df807e0ed3daaa95f5410b..54e97e5bbb8eb641a57e5594f472109cb3a57c7c 100644 (file)
@@ -223,12 +223,63 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
                close(rtc);
 }
 
+/*
+ * At system boot, kernel may set system time from RTC,
+ * but it knows nothing about timezones. If RTC is in local time,
+ * then system time is wrong - it is offset by timezone.
+ * This option corrects system time if RTC is in local time,
+ * and (always) sets in-kernel timezone.
+ *
+ * This is an alternate option to --hctosys that does not read the
+ * hardware clock.
+ */
+static void set_system_clock_timezone(int utc)
+{
+       struct timeval tv;
+       struct tm *broken;
+       struct timezone tz;
+
+       gettimeofday(&tv, NULL);
+       broken = localtime(&tv.tv_sec);
+       tz.tz_minuteswest = timezone / 60;
+       if (broken->tm_isdst)
+               tz.tz_minuteswest -= 60;
+       tz.tz_dsttime = 0;
+       gettimeofday(&tv, NULL);
+       if (!utc)
+               tv.tv_sec += tz.tz_minuteswest * 60;
+       if (settimeofday(&tv, &tz))
+               bb_perror_msg_and_die("settimeofday");
+}
+
+//usage:#define hwclock_trivial_usage
+//usage:       IF_FEATURE_HWCLOCK_LONG_OPTIONS(
+//usage:       "[-r|--show] [-s|--hctosys] [-w|--systohc] [-t|--systz]"
+//usage:       " [-l|--localtime] [-u|--utc]"
+//usage:       " [-f|--rtc FILE]"
+//usage:       )
+//usage:       IF_NOT_FEATURE_HWCLOCK_LONG_OPTIONS(
+//usage:       "[-r] [-s] [-w] [-t] [-l] [-u] [-f FILE]"
+//usage:       )
+//usage:#define hwclock_full_usage "\n\n"
+//usage:       "Query and set hardware clock (RTC)\n"
+//usage:     "\nOptions:"
+//usage:     "\n       -r      Show hardware clock time"
+//usage:     "\n       -s      Set system time from hardware clock"
+//usage:     "\n       -w      Set hardware clock from system time"
+//usage:     "\n       -t      Set in-kernel timezone, correct system time"
+//usage:     "\n               if hardware clock is in local time"
+//usage:     "\n       -u      Hardware clock is in UTC"
+//usage:     "\n       -l      Hardware clock is in local time"
+//usage:     "\n       -f FILE Use specified device (e.g. /dev/rtc2)"
+
 #define HWCLOCK_OPT_LOCALTIME   0x01
 #define HWCLOCK_OPT_UTC         0x02
 #define HWCLOCK_OPT_SHOW        0x04
 #define HWCLOCK_OPT_HCTOSYS     0x08
 #define HWCLOCK_OPT_SYSTOHC     0x10
-#define HWCLOCK_OPT_RTCFILE     0x20
+#define HWCLOCK_OPT_SYSTZ       0x20
+#define HWCLOCK_OPT_RTCFILE     0x40
 
 int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int hwclock_main(int argc UNUSED_PARAM, char **argv)
@@ -239,17 +290,18 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
 
 #if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS
        static const char hwclock_longopts[] ALIGN1 =
-               "localtime\0" No_argument "l"
+               "localtime\0" No_argument "l" /* short opt is non-standard */
                "utc\0"       No_argument "u"
                "show\0"      No_argument "r"
                "hctosys\0"   No_argument "s"
                "systohc\0"   No_argument "w"
-               "file\0"      Required_argument "f"
+               "systz\0"     No_argument "t" /* short opt is non-standard */
+               "rtc\0"       Required_argument "f"
                ;
        applet_long_options = hwclock_longopts;
 #endif
-       opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l";
-       opt = getopt32(argv, "lurswf:", &rtcname);
+       opt_complementary = "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l";
+       opt = getopt32(argv, "lurswtf:", &rtcname);
 
        /* If -u or -l wasn't given check if we are using utc */
        if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
@@ -261,6 +313,8 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
                to_sys_clock(&rtcname, utc);
        else if (opt & HWCLOCK_OPT_SYSTOHC)
                from_sys_clock(&rtcname, utc);
+       else if (opt & HWCLOCK_OPT_SYSTZ)
+               set_system_clock_timezone(utc);
        else
                /* default HWCLOCK_OPT_SHOW */
                show_clock(&rtcname, utc);