nsh/timedatectl: add timedatectl to get/set TZ

follow https://man7.org/linux/man-pages/man1/timedatectl.1.html

nsh> timedatectl
      TimeZone: CST, 28800
    Local time: Sat, Apr 02 05:59:43 2022 CST
Universal time: Fri, Apr 01 21:59:43 2022 GMT
      RTC time: Sun, Apr 01 21:59:42 2022

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-04-01 22:08:11 +08:00 committed by Xiang Xiao
parent 5b0b44f24e
commit 63f28099e3
4 changed files with 123 additions and 0 deletions

View File

@ -245,6 +245,10 @@ config NSH_DISABLE_CMP
bool "Disable cmp"
default DEFAULT_SMALL
config NSH_DISABLE_TIMEDATECTL
bool "Disable TIMEDATECTL"
default DEFAULT_SMALL || !LIBC_LOCALTIME || !RTC
config NSH_DISABLE_DATE
bool "Disable date"
default DEFAULT_SMALL || !RTC

View File

@ -977,6 +977,10 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
int cmd_lbracket(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_NSH_DISABLE_TIMEDATECTL
int cmd_timedatectl(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_NSH_DISABLE_DATE
int cmd_date(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif

View File

@ -154,6 +154,11 @@ static const struct cmdmap_s g_cmdmap[] =
{ "dirname", cmd_dirname, 2, 2, "<path>" },
#endif
#ifndef CONFIG_NSH_DISABLE_TIMEDATECTL
{ "timedatectl", cmd_timedatectl, 1, 3, "[set-timezone TZ]"
},
#endif
#ifndef CONFIG_NSH_DISABLE_DATE
{ "date", cmd_date, 1, 4, "[-s \"MMM DD HH:MM:SS YYYY\"] [-u]" },
#endif

View File

@ -28,6 +28,12 @@
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <nuttx/timers/rtc.h>
#include "nsh.h"
#include "nsh_console.h"
@ -421,3 +427,107 @@ errout:
return ERROR;
}
#endif
/****************************************************************************
* Name: cmd_timedatectl
****************************************************************************/
#ifndef CONFIG_NSH_DISABLE_TIMEDATECTL
int cmd_timedatectl(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char timbuf[MAX_TIME_STRING];
FAR char *newtz = NULL;
struct timespec ts;
struct tm tm;
int ret;
if (argc == 3 && strcmp(argv[1], "set-timezone") == 0)
{
newtz = argv[2];
}
/* Display or set the timedatectl */
if (newtz)
{
ret = setenv("TZ", newtz, true);
if (ret != 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
return ERROR;
}
tzset();
}
else
{
ret = clock_gettime(CLOCK_REALTIME, &ts);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "clock_gettime",
NSH_ERRNO);
return ERROR;
}
if (localtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "localtime_r", NSH_ERRNO);
return ERROR;
}
/* Show the current time in the requested format */
ret = strftime(timbuf, MAX_TIME_STRING, "%a, %b %d %H:%M:%S %Y", &tm);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "strftime", NSH_ERRNO);
return ERROR;
}
nsh_output(vtbl, " TimeZone: %s, %ld\n", tm.tm_zone,
tm.tm_gmtoff);
nsh_output(vtbl, " Local time: %s %s\n", timbuf, tm.tm_zone);
if (gmtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "gmtime_r", NSH_ERRNO);
return ERROR;
}
/* Show the current time in the requested format */
ret = strftime(timbuf, MAX_TIME_STRING, "%a, %b %d %H:%M:%S %Y", &tm);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "strftime", NSH_ERRNO);
return ERROR;
}
nsh_output(vtbl, "Universal time: %s %s\n", timbuf, tm.tm_zone);
ret = open("/dev/rtc0", O_RDONLY);
if (ret > 0)
{
struct rtc_time rtctime;
ioctl(ret, RTC_RD_TIME, &rtctime);
close(ret);
/* Show the current time in the requested format */
ret = strftime(timbuf, MAX_TIME_STRING, "%a, %b %d %H:%M:%S %Y",
(FAR struct tm *)&rtctime);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "strftime",
NSH_ERRNO);
return ERROR;
}
nsh_output(vtbl, " RTC time: %s\n", timbuf);
}
}
return ret;
}
#endif