| 1 | --- a/coreutils/date.c |
| 2 | +++ b/coreutils/date.c |
| 3 | @@ -123,6 +123,7 @@ |
| 4 | //usage: IF_FEATURE_DATE_ISOFMT( |
| 5 | //usage: "\n -D FMT Use FMT for -d TIME conversion" |
| 6 | //usage: ) |
| 7 | +//usage: "\n -k Set Kernel timezone from localtime and exit" |
| 8 | //usage: "\n" |
| 9 | //usage: "\nRecognized TIME formats:" |
| 10 | //usage: "\n hh:mm[:ss]" |
| 11 | @@ -135,6 +136,7 @@ |
| 12 | //usage: "Wed Apr 12 18:52:41 MDT 2000\n" |
| 13 | |
| 14 | #include "libbb.h" |
| 15 | +#include <sys/time.h> |
| 16 | #if ENABLE_FEATURE_DATE_NANO |
| 17 | # include <sys/syscall.h> |
| 18 | #endif |
| 19 | @@ -145,8 +147,9 @@ enum { |
| 20 | OPT_UTC = (1 << 2), /* u */ |
| 21 | OPT_DATE = (1 << 3), /* d */ |
| 22 | OPT_REFERENCE = (1 << 4), /* r */ |
| 23 | - OPT_TIMESPEC = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ |
| 24 | - OPT_HINT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ |
| 25 | + OPT_KERNELTZ = (1 << 5), /* k */ |
| 26 | + OPT_TIMESPEC = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ |
| 27 | + OPT_HINT = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ |
| 28 | }; |
| 29 | |
| 30 | static void maybe_set_utc(int opt) |
| 31 | @@ -164,12 +167,15 @@ static const char date_longopts[] ALIGN1 |
| 32 | /* "universal\0" No_argument "u" */ |
| 33 | "date\0" Required_argument "d" |
| 34 | "reference\0" Required_argument "r" |
| 35 | + "set-kernel-tz\0" No_argument "k" |
| 36 | ; |
| 37 | #endif |
| 38 | |
| 39 | int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 40 | int date_main(int argc UNUSED_PARAM, char **argv) |
| 41 | { |
| 42 | + time_t tt; |
| 43 | + struct timezone tz; |
| 44 | struct timespec ts; |
| 45 | struct tm tm_time; |
| 46 | char buf_fmt_dt2str[64]; |
| 47 | @@ -184,7 +190,7 @@ int date_main(int argc UNUSED_PARAM, cha |
| 48 | opt_complementary = "d--s:s--d" |
| 49 | IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); |
| 50 | IF_LONG_OPTS(applet_long_options = date_longopts;) |
| 51 | - opt = getopt32(argv, "Rs:ud:r:" |
| 52 | + opt = getopt32(argv, "Rs:ud:r:k" |
| 53 | IF_FEATURE_DATE_ISOFMT("I::D:"), |
| 54 | &date_str, &date_str, &filename |
| 55 | IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); |
| 56 | @@ -241,6 +247,27 @@ int date_main(int argc UNUSED_PARAM, cha |
| 57 | if (*argv) |
| 58 | bb_show_usage(); |
| 59 | |
| 60 | + /* Setting of kernel timezone was requested */ |
| 61 | + if (opt & OPT_KERNELTZ) { |
| 62 | + tt = time(NULL); |
| 63 | + localtime_r(&tt, &tm_time); |
| 64 | + |
| 65 | + /* workaround warp_clock() on first invocation */ |
| 66 | + memset(&tz, 0, sizeof(tz)); |
| 67 | + settimeofday(NULL, &tz); |
| 68 | + |
| 69 | + memset(&tz, 0, sizeof(tz)); |
| 70 | + tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60); |
| 71 | + |
| 72 | + if (settimeofday(NULL, &tz)) |
| 73 | + { |
| 74 | + bb_perror_msg("can't set kernel time zone"); |
| 75 | + return EXIT_FAILURE; |
| 76 | + } |
| 77 | + |
| 78 | + return EXIT_SUCCESS; |
| 79 | + } |
| 80 | + |
| 81 | /* Now we have parsed all the information except the date format |
| 82 | * which depends on whether the clock is being set or read */ |
| 83 | |
| 84 | |