[Crash-utility] [PATCH] Append time zone to output of date and time
Mathias Krause
minipli at grsecurity.net
Wed Aug 19 14:16:40 UTC 2020
Hi Kazuhito,
Am 19.08.20 um 08:32 schrieb HAGIO KAZUHITO(萩尾 一仁):
> Currently it's not easy to distinguish which time zone the output of
> DATE uses:
>
> crash> sys | grep DATE
> DATE: Thu Nov 29 06:44:02 2018
>
> Let's introduce ctime_tz() function like ctime() but explicitly appends
> the time zone to its result string.
>
> DATE: Thu Nov 29 06:44:02 JST 2018
>
> Resolves: https://github.com/crash-utility/crash/issues/62
> Suggested-by: Jacob Wen <jian.w.wen at oracle.com>
> Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
> ---
> defs.h | 1 +
> help.c | 3 +--
> kernel.c | 16 ++++++----------
> tools.c | 28 ++++++++++++++++++++++++++++
> 4 files changed, 36 insertions(+), 12 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index 17e98763362b..e7dec7c672a6 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -5096,6 +5096,7 @@ char *strdupbuf(char *);
> void sigsetup(int, void *, struct sigaction *, struct sigaction *);
> #define SIGACTION(s, h, a, o) sigsetup(s, h, a, o)
> char *convert_time(ulonglong, char *);
> +char *ctime_tz(time_t *);
> void stall(ulong);
> char *pages_to_size(ulong, char *);
> int clean_arg(void);
> diff --git a/help.c b/help.c
> index b707cfa58826..d3427a36829f 100644
> --- a/help.c
> +++ b/help.c
> @@ -9299,8 +9299,7 @@ display_README(void)
> fprintf(fp, " GNU gdb %s\n", pc->gdb_version);
> } else if (STREQ(README[i], README_DATE)) {
> time(&time_now);
> - fprintf(fp, " DATE: %s\n",
> - strip_linefeeds(ctime(&time_now)));
> + fprintf(fp, " DATE: %s\n", ctime_tz(&time_now));
> } else if (STREQ(README[i], README_HELP_MENU)) {
> display_help_screen(" ");
> } else if (STREQ(README[i], README_GPL_INFO)) {
> diff --git a/kernel.c b/kernel.c
> index f179375f2d3d..92bfe6329900 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -225,10 +225,9 @@ kernel_init()
> get_xtime(&kt->date);
> if (CRASHDEBUG(1))
> fprintf(fp, "xtime timespec.tv_sec: %lx: %s\n",
> - kt->date.tv_sec, strip_linefeeds(ctime(&kt->date.tv_sec)));
> + kt->date.tv_sec, ctime_tz(&kt->date.tv_sec));
> if (kt->flags2 & GET_TIMESTAMP) {
> - fprintf(fp, "%s\n\n",
> - strip_linefeeds(ctime(&kt->date.tv_sec)));
> + fprintf(fp, "%s\n\n", ctime_tz(&kt->date.tv_sec));
> clean_exit(0);
> }
>
> @@ -5178,7 +5177,7 @@ dump_log_entry(char *logptr, int msg_flags)
> rem = (ulonglong)ts_nsec % (ulonglong)1000000000;
> if (msg_flags & SHOW_LOG_CTIME) {
> time_t t = kt->boot_date.tv_sec + nanos;
> - sprintf(buf, "[%s] ", strip_linefeeds(ctime(&t)));
> + sprintf(buf, "[%s] ", ctime_tz(&t));
> }
> else
> sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000);
> @@ -5553,8 +5552,7 @@ display_sys_stats(void)
>
> if (ACTIVE())
> get_xtime(&kt->date);
> - fprintf(fp, " DATE: %s\n",
> - strip_linefeeds(ctime(&kt->date.tv_sec)));
> + fprintf(fp, " DATE: %s\n", ctime_tz(&kt->date.tv_sec));
> fprintf(fp, " UPTIME: %s\n", get_uptime(buf, NULL));
> fprintf(fp, "LOAD AVERAGE: %s\n", get_loadavg(buf));
> fprintf(fp, " TASKS: %ld\n", RUNNING_TASKS());
> @@ -6043,10 +6041,8 @@ dump_kernel_table(int verbose)
> kt->source_tree : "(not used)");
> if (!(pc->flags & KERNEL_DEBUG_QUERY) && ACTIVE())
> get_xtime(&kt->date);
> - fprintf(fp, " date: %s\n",
> - strip_linefeeds(ctime(&kt->date.tv_sec)));
> - fprintf(fp, " boot_ date: %s\n",
> - strip_linefeeds(ctime(&kt->boot_date.tv_sec)));
> + fprintf(fp, " date: %s\n", ctime_tz(&kt->date.tv_sec));
> + fprintf(fp, " boot_date: %s\n", ctime_tz(&kt->boot_date.tv_sec));
> fprintf(fp, " proc_version: %s\n", strip_linefeeds(kt->proc_version));
> fprintf(fp, " new_utsname: \n");
> fprintf(fp, " .sysname: %s\n", uts->sysname);
> diff --git a/tools.c b/tools.c
> index 85c81668e40e..4654e7458a3e 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -6318,6 +6318,34 @@ convert_time(ulonglong count, char *buf)
> }
>
> /*
> + * Convert a calendar time into a null-terminated string like ctime(), but
> + * the result string contains the time zone string and does not ends with a
> + * linefeed ('\n').
> + *
> + * NOTE: The return value points to a statically allocated string which is
> + * overwritten by subsequent calls.
> + */
> +char *
> +ctime_tz(time_t *timep)
> +{
> + static char buf[64];
> + struct tm *tm;
> + size_t size;
> +
> + tm = localtime(timep);
> + if (!tm) {
> + snprintf(buf, sizeof(buf), "%ld", *timep);
> + return buf;
> + }
I don't think this is especially useful, better fall back to ctime() in
this case, but see below.
> +
> + size = strftime(buf, sizeof(buf), "%a %b %e %T %Z %Y", tm);
> + if (!size)
> + return strip_linefeeds(ctime(timep));
Maybe you should mention in the leading comment that this function falls
back to ctime() in case it fails to generate a timestamp with the time
zone info?
> +
> + return buf;
> +}
> +
> +/*
> * Stall for a number of microseconds.
> */
> void
So, to simplify ctime_tz() and avoid the "UNIX seconds since epoch" case
I'd suggest something like this instead:
char *
ctime_tz(time_t *timep)
{
static char buf[64];
struct tm *tm;
tm = localtime(timep);
if (tm && strftime(buf, sizeof(buf), "%a %b %e %T %Z %Y", tm))
return buf;
return strip_linefeeds(ctime(timep));
}
Beside that, patch looks good to me!
Thanks,
Mathias
More information about the Crash-utility
mailing list