From a675eaec5aef0089b6838aca8fd432fea0bd883b Mon Sep 17 00:00:00 2001 From: Piotr Pawel Stefaniak Date: Sun, 1 Jan 2023 20:38:35 +0100 Subject: [PATCH] sh: implement PS1 \D to print current time \D{format} yields the result of calling strftime(3) with the provided format and the current time. When PS4 can use this, it will enable us to easily generate timestamps when tracing script execution. Differential Revision: https://reviews.freebsd.org/D35840 --- bin/sh/parser.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ bin/sh/sh.1 | 10 ++++++++++ 2 files changed, 54 insertions(+) diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 121c367c601..8e959b46596 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -43,6 +43,7 @@ static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; #include #include #include +#include #include "shell.h" #include "parser.h" @@ -2100,6 +2101,49 @@ getprompt(void *unused __unused) } break; + /* + * Print the current time as per provided strftime format. + */ + case 'D': { + char tfmt[128] = "%X"; /* \D{} means %X. */ + struct tm *now; + + if (fmt[1] != '{') { + /* + * "\D" but not "\D{", so treat the '\' + * literally and rewind fmt to treat 'D' + * literally next iteration. + */ + ps[i] = '\\'; + fmt--; + break; + } + fmt += 2; /* Consume "D{". */ + if (fmt[0] != '}') { + char *end; + + end = memccpy(tfmt, fmt, '}', sizeof(tfmt)); + if (end == NULL) { + /* + * Format too long or no '}', so + * ignore "\D{" altogether. + * The loop will do i++, but nothing + * was written to ps, so do i-- here. + * Rewind fmt for similar reason. + */ + i--; + fmt--; + break; + } + *--end = '\0'; /* Ignore the copy of '}'. */ + fmt += end - tfmt; + } + now = localtime(&(time_t){time(NULL)}); + i += strftime(&ps[i], PROMPTLEN - i - 1, tfmt, now); + i--; /* The loop will do i++. */ + break; + } + /* * Hostname. * diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index fb3afc7d3d4..adbc3282704 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -1427,6 +1427,16 @@ unless you are the superuser, in which case it defaults to may include any of the following formatting sequences, which are replaced by the given information: .Bl -tag -width indent +.It Li \eD{format} +The current time in +.Xr strftime 3 +.Ar format . +The braces are required. +Empty +.Ar format +is equivalent to +\&%X, +national representation of the time. .It Li \eH This system's fully-qualified hostname (FQDN). .It Li \eh