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
This commit is contained in:
Piotr Pawel Stefaniak 2023-01-01 20:38:35 +01:00
parent f80babf906
commit a675eaec5a
2 changed files with 54 additions and 0 deletions

View file

@ -43,6 +43,7 @@ static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#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.
*

View file

@ -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