aboutsummaryrefslogtreecommitdiffstats
path: root/package/utils/busybox/patches/250-date-k-flag.patch
blob: 3a85312e2f19fc66369b66b0688df66f1e6587cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
--- 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]"
@@ -139,9 +140,8 @@
 
 #include "libbb.h"
 #include "common_bufsiz.h"
-#if ENABLE_FEATURE_DATE_NANO
-# include <sys/syscall.h>
-#endif
+#include <sys/time.h>
+#include <sys/syscall.h>
 
 enum {
 	OPT_RFC2822   = (1 << 0), /* R */
@@ -149,8 +149,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 */
 };
 
 #if ENABLE_LONG_OPTS
@@ -162,6 +163,7 @@ 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
 
@@ -181,6 +183,8 @@ static void maybe_set_utc(int opt)
 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];
@@ -193,7 +197,7 @@ int date_main(int argc UNUSED_PARAM, cha
 	char *isofmt_arg = NULL;
 
 	opt = getopt32long(argv, "^"
-			"Rs:ud:r:"
+			"Rs:ud:r:k"
 			IF_FEATURE_DATE_ISOFMT("I::D:")
 			"\0"
 			"d--s:s--d"
@@ -256,6 +260,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));
+		syscall(SYS_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 (syscall(SYS_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 */