aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-06-04 18:19:15 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-06-04 18:19:15 +0200
commit6c2406ac861f42536acb76606c90412324a0e733 (patch)
treee5a06a205f1590eadb267a78bb3a706f359243d3
parent8878c24c7d15fe0d4df73aa8477251c6583f5157 (diff)
downloadbusybox-w32-6c2406ac861f42536acb76606c90412324a0e733.tar.gz
busybox-w32-6c2406ac861f42536acb76606c90412324a0e733.tar.bz2
busybox-w32-6c2406ac861f42536acb76606c90412324a0e733.zip
date: optional support for %N. Closes bug 1861.
function old new delta date_main 862 1090 +228 clock_gettime - 41 +41 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/0 up/down: 269/0) Total: 269 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/Config.in7
-rw-r--r--coreutils/date.c59
2 files changed, 60 insertions, 6 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in
index ead632a31..37e885c1c 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -115,6 +115,13 @@ config FEATURE_DATE_ISOFMT
115 Enable option (-I) to output an ISO-8601 compliant 115 Enable option (-I) to output an ISO-8601 compliant
116 date/time string. 116 date/time string.
117 117
118config FEATURE_DATE_NANO
119 bool "Support %[num]N nanosecond format specifier"
120 default y
121 depends on DATE
122 help
123 Support %[num]N format specifier. Adds ~250 bytes of code.
124
118config FEATURE_DATE_COMPAT 125config FEATURE_DATE_COMPAT
119 bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format" 126 bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format"
120 default y 127 default y
diff --git a/coreutils/date.c b/coreutils/date.c
index 4e5b3b0b8..c1390be76 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -84,9 +84,9 @@ static const char date_longopts[] ALIGN1 =
84int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 84int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
85int date_main(int argc UNUSED_PARAM, char **argv) 85int date_main(int argc UNUSED_PARAM, char **argv)
86{ 86{
87 struct timespec ts;
87 struct tm tm_time; 88 struct tm tm_time;
88 char buf_fmt_dt2str[64]; 89 char buf_fmt_dt2str[64];
89 time_t tm;
90 unsigned opt; 90 unsigned opt;
91 int ifmt = -1; 91 int ifmt = -1;
92 char *date_str; 92 char *date_str;
@@ -161,11 +161,18 @@ int date_main(int argc UNUSED_PARAM, char **argv)
161 if (opt & OPT_REFERENCE) { 161 if (opt & OPT_REFERENCE) {
162 struct stat statbuf; 162 struct stat statbuf;
163 xstat(filename, &statbuf); 163 xstat(filename, &statbuf);
164 tm = statbuf.st_mtime; 164 ts.tv_sec = statbuf.st_mtime;
165#if ENABLE_FEATURE_DATE_NANO
166 ts.tv_nsec = statbuf.st_mtimensec; //or st_atim.tv_nsec?
167#endif
165 } else { 168 } else {
166 time(&tm); 169#if ENABLE_FEATURE_DATE_NANO
170 clock_gettime(CLOCK_REALTIME, &ts);
171#else
172 time(&ts.tv_nsec);
173#endif
167 } 174 }
168 localtime_r(&tm, &tm_time); 175 localtime_r(&ts.tv_sec, &tm_time);
169 176
170 /* If date string is given, update tm_time, and maybe set date */ 177 /* If date string is given, update tm_time, and maybe set date */
171 if (date_str != NULL) { 178 if (date_str != NULL) {
@@ -184,12 +191,12 @@ int date_main(int argc UNUSED_PARAM, char **argv)
184 191
185 /* Correct any day of week and day of year etc. fields */ 192 /* Correct any day of week and day of year etc. fields */
186 tm_time.tm_isdst = -1; /* Be sure to recheck dst */ 193 tm_time.tm_isdst = -1; /* Be sure to recheck dst */
187 tm = validate_tm_time(date_str, &tm_time); 194 ts.tv_sec = validate_tm_time(date_str, &tm_time);
188 195
189 maybe_set_utc(opt); 196 maybe_set_utc(opt);
190 197
191 /* if setting time, set it */ 198 /* if setting time, set it */
192 if ((opt & OPT_SET) && stime(&tm) < 0) { 199 if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) {
193 bb_perror_msg("can't set date"); 200 bb_perror_msg("can't set date");
194 } 201 }
195 } 202 }
@@ -222,6 +229,46 @@ int date_main(int argc UNUSED_PARAM, char **argv)
222 fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y"; 229 fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y";
223 } 230 }
224 } 231 }
232#if ENABLE_FEATURE_DATE_NANO
233 else {
234 /* User-specified fmt_dt2str */
235 /* Search for and process "%N" */
236 char *p = fmt_dt2str;
237 while ((p = strchr(p, '%')) != NULL) {
238 int n, m;
239 unsigned pres, scale;
240
241 p++;
242 if (*p == '%') {
243 p++;
244 continue;
245 }
246 n = strspn(p, "0123456789");
247 if (p[n] != 'N') {
248 p += n;
249 continue;
250 }
251 /* We have "%[nnn]N" */
252 p[-1] = '\0';
253 p[n] = '\0';
254 scale = 1;
255 pres = 9;
256 if (n) {
257 pres = xatoi_u(p);
258 if (pres == 0)
259 pres = 9;
260 m = 9 - pres;
261 while (--m >= 0)
262 scale *= 10;
263 }
264
265 m = p - fmt_dt2str;
266 p += n + 1;
267 fmt_dt2str = xasprintf("%s%0*u%s", fmt_dt2str, pres, (unsigned)ts.tv_nsec / scale, p);
268 p = fmt_dt2str + m;
269 }
270 }
271#endif
225 272
226#define date_buf bb_common_bufsiz1 273#define date_buf bb_common_bufsiz1
227 if (*fmt_dt2str == '\0') { 274 if (*fmt_dt2str == '\0') {