--- a/coreutils/date.c +++ b/coreutils/date.c @@ -123,6 +123,7 @@ //usage: IF_FEATURE_DATE_ISOFMT( //usage: "\n -D FMT Use FMT for -d TIME conversion" //usage: ) +//usage: "\n -k Set Kernel timezone from localtime and exit" //usage: "\n" //usage: "\nRecognized TIME formats:" //usage: "\n hh:mm[:ss]" @@ -138,6 +139,7 @@ //usage: "Wed Apr 12 18:52:41 MDT 2000\n" #include "libbb.h" +#include #if ENABLE_FEATURE_DATE_NANO # include #endif @@ -148,8 +150,9 @@ enum { OPT_UTC = (1 << 2), /* u */ OPT_DATE = (1 << 3), /* d */ OPT_REFERENCE = (1 << 4), /* r */ - OPT_TIMESPEC = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ - OPT_HINT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ + OPT_KERNELTZ = (1 << 5), /* k */ + OPT_TIMESPEC = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ + OPT_HINT = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ }; static void maybe_set_utc(int opt) @@ -167,12 +170,15 @@ static const char date_longopts[] ALIGN1 /* "universal\0" No_argument "u" */ "date\0" Required_argument "d" "reference\0" Required_argument "r" + "set-kernel-tz\0" No_argument "k" ; #endif int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int date_main(int argc UNUSED_PARAM, char **argv) { + time_t tt; + struct timezone tz; struct timespec ts; struct tm tm_time; char buf_fmt_dt2str[64]; @@ -187,7 +193,7 @@ int date_main(int argc UNUSED_PARAM, cha opt_complementary = "d--s:s--d" IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); IF_LONG_OPTS(applet_long_options = date_longopts;) - opt = getopt32(argv, "Rs:ud:r:" + opt = getopt32(argv, "Rs:ud:r:k" IF_FEATURE_DATE_ISOFMT("I::D:"), &date_str, &date_str, &filename IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); @@ -244,6 +250,31 @@ int date_main(int argc UNUSED_PARAM, cha if (*argv) bb_show_usage(); + /* Setting of kernel timezone was requested */ + if (opt & OPT_KERNELTZ) { + tt = time(NULL); + localtime_r(&tt, &tm_time); + + /* workaround warp_clock() on first invocation */ + memset(&tz, 0, sizeof(tz)); + settimeofday(NULL, &tz); + + memset(&tz, 0, sizeof(tz)); +#ifdef __USE_MISC + tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60); +#else + tz.tz_minuteswest = -(tm_time.__tm_gmtoff / 60); +#endif + + if (settimeofday(NULL, &tz)) + { + bb_perror_msg("can't set kernel time zone"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } + /* Now we have parsed all the information except the date format * which depends on whether the clock is being set or read */