Rebased from upstream / out of band repository.
[librecmc/librecmc.git] / package / utils / busybox / patches / 250-date-k-flag.patch
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 @@ -139,9 +140,8 @@
12  
13  #include "libbb.h"
14  #include "common_bufsiz.h"
15 -#if ENABLE_FEATURE_DATE_NANO
16 -# include <sys/syscall.h>
17 -#endif
18 +#include <sys/time.h>
19 +#include <sys/syscall.h>
20  
21  enum {
22         OPT_RFC2822   = (1 << 0), /* R */
23 @@ -149,8 +149,9 @@ enum {
24         OPT_UTC       = (1 << 2), /* u */
25         OPT_DATE      = (1 << 3), /* d */
26         OPT_REFERENCE = (1 << 4), /* r */
27 -       OPT_TIMESPEC  = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
28 -       OPT_HINT      = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
29 +       OPT_KERNELTZ  = (1 << 5), /* k */
30 +       OPT_TIMESPEC  = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
31 +       OPT_HINT      = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
32  };
33  
34  #if ENABLE_LONG_OPTS
35 @@ -162,6 +163,7 @@ static const char date_longopts[] ALIGN1
36         /*      "universal\0" No_argument       "u" */
37                 "date\0"      Required_argument "d"
38                 "reference\0" Required_argument "r"
39 +               "set-kernel-tz\0" No_argument   "k"
40                 ;
41  #endif
42  
43 @@ -181,6 +183,8 @@ static void maybe_set_utc(int opt)
44  int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
45  int date_main(int argc UNUSED_PARAM, char **argv)
46  {
47 +       time_t tt;
48 +       struct timezone tz;
49         struct timespec ts;
50         struct tm tm_time;
51         char buf_fmt_dt2str[64];
52 @@ -193,7 +197,7 @@ int date_main(int argc UNUSED_PARAM, cha
53         char *isofmt_arg = NULL;
54  
55         opt = getopt32long(argv, "^"
56 -                       "Rs:ud:r:"
57 +                       "Rs:ud:r:k"
58                         IF_FEATURE_DATE_ISOFMT("I::D:")
59                         "\0"
60                         "d--s:s--d"
61 @@ -256,6 +260,31 @@ int date_main(int argc UNUSED_PARAM, cha
62         if (*argv)
63                 bb_show_usage();
64  
65 +       /* Setting of kernel timezone was requested */
66 +       if (opt & OPT_KERNELTZ) {
67 +               tt = time(NULL);
68 +               localtime_r(&tt, &tm_time);
69 +
70 +               /* workaround warp_clock() on first invocation */
71 +               memset(&tz, 0, sizeof(tz));
72 +               syscall(SYS_settimeofday, NULL, &tz);
73 +
74 +               memset(&tz, 0, sizeof(tz));
75 +#ifdef __USE_MISC
76 +               tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60);
77 +#else
78 +               tz.tz_minuteswest = -(tm_time.__tm_gmtoff / 60);
79 +#endif
80 +
81 +               if (syscall(SYS_settimeofday, NULL, &tz))
82 +               {
83 +                       bb_perror_msg("can't set kernel time zone");
84 +                       return EXIT_FAILURE;
85 +               }
86 +
87 +               return EXIT_SUCCESS;
88 +       }
89 +
90         /* Now we have parsed all the information except the date format
91          * which depends on whether the clock is being set or read */
92