Skip to content

Commit 228a9a4

Browse files
author
Biancaa Ramesh
committed
nshlib: fix ls_handler style compliance and add host sync
a) Added time module only incase of simulation. b) Used linux/cpu based functions for getting time only then. c) Checked if the device is timekeeping before ls-l for accuracy. d) if hostfs present syncing new file time to /data. e) Manual epoch-time calculation to fit it in microcontrollers. Signed-off-by: Biancaa Ramesh <biancaa2210329@ssn.edu.in>
1 parent 9e89e40 commit 228a9a4

File tree

1 file changed

+126
-62
lines changed

1 file changed

+126
-62
lines changed

nshlib/nsh_fscmds.c

Lines changed: 126 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@
4444
#include <libgen.h>
4545
#include <errno.h>
4646
#include <debug.h>
47-
#include <time.h>
4847
#include "nsh.h"
4948

50-
#define CONFIG_LIBC_LOCALTIME 1
51-
#define CONFIG_CLOCK_TIMEKEEPING 1
52-
49+
#ifdef CONFIG_ARCH_SIM
50+
# include <time.h>
51+
#endif
5352

5453
#if !defined(CONFIG_DISABLE_MOUNTPOINT)
5554
# include <sys/mount.h>
@@ -364,52 +363,132 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath,
364363

365364
if ((lsflags & (LSFLAGS_SIZE | LSFLAGS_LONG | LSFLAGS_UID_GID)) != 0)
366365
{
367-
struct stat buf;
366+
struct stat buf;
368367

369-
memset(&buf, 0, sizeof(buf));
368+
memset(&buf, 0, sizeof(struct stat));
370369

371-
/* stat the file */
372-
if (entryp != NULL)
373-
{
374-
FAR char *fullpath = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
375-
ret = stat(fullpath, &buf);
376-
free(fullpath);
377-
}
378-
else
379-
{
380-
ret = stat(dirpath, &buf);
381-
}
370+
/* If entryp is provided, listing a directory and need to
371+
* construct the full path to stat the file. Otherwise, dirpath
372+
* is the target itself. (no separate file name as entryp)
373+
*/
382374

383-
#ifdef CONFIG_CLOCK_TIMEKEEPING
384-
if (ret == 0 && buf.st_mtime > 0 && buf.st_mtime < 0x7FFFFFFF)
385-
{
386-
struct tm tm;
387-
time_t t = buf.st_mtime;
375+
if (entryp != NULL)
376+
{
377+
FAR char *fullpath = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
378+
ret = stat(fullpath, &buf);
379+
free(fullpath);
380+
}
381+
else
382+
{
383+
ret = stat(dirpath, &buf);
384+
}
388385

389-
#ifdef CONFIG_LIBC_LOCALTIME
390-
localtime_r(&t, &tm);
391-
nsh_output(vtbl, " %04d-%02d-%02d %02d:%02d",
392-
tm.tm_year + 1900,
393-
tm.tm_mon + 1,
394-
tm.tm_mday,
395-
tm.tm_hour,
396-
tm.tm_min);
397-
#else
398-
nsh_output(vtbl, " %ld", (long)t);
399-
#endif
400-
}
401-
else
402-
{
403-
nsh_output(vtbl, " ----/--/-- --:--");
404-
}
405-
#endif
386+
#ifdef CONFIG_CLOCK_TIMEKEEPING
387+
/* manual epoch time to date calculation to reduce extra memory
388+
* by using includes For boards with minimal flash.
389+
*/
390+
391+
# ifdef CONFIG_ARCH_SIM
392+
struct timespec ts;
393+
394+
/* This pulls the ACTUAL current time from your Linux Host */
395+
396+
/* Sometime defaults to 2008 */
397+
398+
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
399+
{
400+
clock_settime(CLOCK_REALTIME, &ts);
401+
}
402+
# endif
403+
404+
/* for referencing /data : if not mounted the reference will fail. */
405+
406+
# if defined(CONFIG_ARCH_SIM) && defined(CONFIG_FS_HOSTFS)
407+
static bool g_time_synced = false;
408+
409+
if (!g_time_synced)
410+
{
411+
struct stat hstat;
412+
413+
/* Data section always maintains the current time value. */
414+
415+
if (stat("/data", &hstat) == 0)
416+
{
417+
struct timespec ts_sync;
418+
419+
ts_sync.tv_sec = hstat.st_mtime;
420+
ts_sync.tv_nsec = 0;
406421

422+
/* This is the magic line that sets the system clock */
407423

408-
memset(&buf, 0, sizeof(struct stat));
424+
if (clock_settime(CLOCK_REALTIME, &ts_sync) == 0)
425+
{
426+
g_time_synced = true;
427+
}
428+
}
429+
}
430+
# endif
431+
432+
if (ret == 0 && buf.st_mtime > 0 && buf.st_mtime < 0x7fffffff)
433+
{
434+
uint32_t seconds = (uint32_t)buf.st_mtime;
435+
uint32_t minutes = seconds / 60;
436+
uint32_t hours = minutes / 60;
437+
uint32_t days = hours / 24;
438+
uint32_t y = 1970;
439+
uint32_t m = 0;
440+
441+
while (1)
442+
{
443+
uint32_t diy = (y % 4 == 0 && (y % 100 != 0 ||
444+
y % 400 == 0)) ? 366 : 365;
445+
446+
if (days < diy)
447+
{
448+
break;
449+
}
450+
451+
days -= diy;
452+
y++;
453+
}
454+
455+
static const uint8_t dim[] =
456+
{
457+
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
458+
};
459+
460+
for (m = 0; m < 12; m++)
461+
{
462+
uint32_t d_m = dim[m];
463+
464+
if (m == 1 && (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)))
465+
{
466+
d_m = 29;
467+
}
468+
469+
if (days < d_m)
470+
{
471+
break;
472+
}
473+
474+
days -= d_m;
475+
}
476+
477+
nsh_output(vtbl, " %04u-%02u-%02u %02u:%02u:%02u",
478+
(unsigned int)y, (unsigned int)m + 1,
479+
(unsigned int)days + 1, (unsigned int)(hours % 24),
480+
(unsigned int)(minutes % 60),
481+
(unsigned int)(seconds % 60));
482+
}
483+
else
484+
{
485+
/* Incase valid time entry was not maintained in the stat struct. */
409486

410-
/* stat the file */
487+
nsh_output(vtbl, " ----/--/-- --:--");
488+
}
489+
#endif
411490

412-
if (entryp != NULL)
491+
if (entryp != NULL)
413492
{
414493
FAR char *fullpath = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
415494
ret = stat(fullpath, &buf);
@@ -561,39 +640,24 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath,
561640

562641
if ((lsflags & LSFLAGS_SIZE) != 0)
563642
{
643+
#ifdef CONFIG_HAVE_FLOAT
564644
if (lsflags & LSFLAGS_HUMANREADBLE && buf.st_size >= KB)
565645
{
566-
uint32_t integer_part;
567-
uint32_t decimal_part;
568-
uint32_t unit;
569-
char suffix;
570-
571-
/* Determine the appropriate unit and suffix */
572-
573646
if (buf.st_size >= GB)
574647
{
575-
unit = GB;
576-
suffix = 'G';
648+
nsh_output(vtbl, "%11.1fG", (float)buf.st_size / GB);
577649
}
578650
else if (buf.st_size >= MB)
579651
{
580-
unit = MB;
581-
suffix = 'M';
652+
nsh_output(vtbl, "%11.1fM", (float)buf.st_size / MB);
582653
}
583654
else
584655
{
585-
unit = KB;
586-
suffix = 'K';
656+
nsh_output(vtbl, "%11.1fK", (float)buf.st_size / KB);
587657
}
588-
589-
/* Use integer arithmetic to avoid floating point */
590-
591-
integer_part = buf.st_size / unit;
592-
decimal_part = ((buf.st_size % unit) * 10) / unit;
593-
nsh_output(vtbl, "%10" PRIu32 ".%" PRIu32 "%c",
594-
integer_part, decimal_part, suffix);
595658
}
596659
else
660+
#endif
597661
{
598662
nsh_output(vtbl, "%12" PRIdOFF, buf.st_size);
599663
}

0 commit comments

Comments
 (0)