From 63f28099e399b05bf8e2c3dfc83c006aa753304d Mon Sep 17 00:00:00 2001 From: Jiuzhu Dong Date: Fri, 1 Apr 2022 22:08:11 +0800 Subject: [PATCH] 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 --- nshlib/Kconfig | 4 ++ nshlib/nsh.h | 4 ++ nshlib/nsh_command.c | 5 ++ nshlib/nsh_timcmds.c | 110 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) diff --git a/nshlib/Kconfig b/nshlib/Kconfig index b9aba1294..df11aa072 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -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 diff --git a/nshlib/nsh.h b/nshlib/nsh.h index d7d2c5575..539013407 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -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 diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 46a59a54f..0f8bf8680 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -154,6 +154,11 @@ static const struct cmdmap_s g_cmdmap[] = { "dirname", cmd_dirname, 2, 2, "" }, #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 diff --git a/nshlib/nsh_timcmds.c b/nshlib/nsh_timcmds.c index 99b4b20ae..5c9d38fea 100644 --- a/nshlib/nsh_timcmds.c +++ b/nshlib/nsh_timcmds.c @@ -28,6 +28,12 @@ #include #include #include +#include +#include +#include +#include + +#include #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