[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[coreutils] [PATCH 2/2] stat: print timestamps to full resolution
From: |
Eric Blake |
Subject: |
[coreutils] [PATCH 2/2] stat: print timestamps to full resolution |
Date: |
Thu, 30 Sep 2010 17:32:48 -0600 |
* src/stat.c (epoch_time): New function.
(print_stat): Use it for %[WXYZ].
* NEWS: Document this.
* tests/touch/60-seconds: Adjust test to match.
---
It bugs me that %x has more information than %X in 'stat --format',
especially, since we don't support any format modifiers for getting
at the additional information. We're already incompatible with
BSD stat(1) format modifiers, and there is no standard for stat(1),
so I wasn't too worried about changing the meaning of existing
modifiers rather than burning new letters just for the nanosecond
portions. And now that POSIX 2008 requires nanonsecond resolution
in stat(2), you could argue that we should always be displaying it.
NEWS | 3 +++
src/stat.c | 32 +++++++++++++++++---------------
tests/touch/60-seconds | 2 +-
3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/NEWS b/NEWS
index 0c7cc38..690f693 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,9 @@ GNU coreutils NEWS -*-
outline -*-
for a file. It also accepts the %w and %W format directives for
outputting the birth time of a file, if one is available.
+ stat now outputs the full timestamp resolution for the %X, %Y, and
+ %Z format directives.
+
** Changes in behavior
df now consistently prints the device name for a bind mounted file,
diff --git a/src/stat.c b/src/stat.c
index c465e77..fb9b2c2 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -461,6 +461,19 @@ human_time (struct timespec t)
return str;
}
+static char * ATTRIBUTE_WARN_UNUSED_RESULT
+epoch_time (struct timespec t)
+{
+ static char str[INT_STRLEN_BOUND (time_t) + sizeof ".NNNNNNNNN"];
+ if (TYPE_SIGNED (time_t))
+ sprintf (str, "%" PRIdMAX ".%09lu", (intmax_t) t.tv_sec,
+ (unsigned long) t.tv_nsec);
+ else
+ sprintf (str, "%" PRIuMAX ".%09lu", (uintmax_t) t.tv_sec,
+ (unsigned long) t.tv_nsec);
+ return str;
+}
+
static void
out_string (char *pformat, size_t prefix_len, char const *arg)
{
@@ -802,38 +815,27 @@ print_stat (char *pformat, size_t prefix_len, char m,
struct timespec t = get_stat_birthtime (statbuf);
if (t.tv_nsec < 0)
out_string (pformat, prefix_len, "-");
- else if (TYPE_SIGNED (time_t))
- out_int (pformat, prefix_len, t.tv_sec);
else
- out_uint (pformat, prefix_len, t.tv_sec);
+ out_string (pformat, prefix_len, epoch_time (t));
}
break;
case 'x':
out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
break;
case 'X':
- if (TYPE_SIGNED (time_t))
- out_int (pformat, prefix_len, statbuf->st_atime);
- else
- out_uint (pformat, prefix_len, statbuf->st_atime);
+ out_string (pformat, prefix_len, epoch_time (get_stat_atime (statbuf)));
break;
case 'y':
out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf)));
break;
case 'Y':
- if (TYPE_SIGNED (time_t))
- out_int (pformat, prefix_len, statbuf->st_mtime);
- else
- out_uint (pformat, prefix_len, statbuf->st_mtime);
+ out_string (pformat, prefix_len, epoch_time (get_stat_mtime (statbuf)));
break;
case 'z':
out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf)));
break;
case 'Z':
- if (TYPE_SIGNED (time_t))
- out_int (pformat, prefix_len, statbuf->st_ctime);
- else
- out_uint (pformat, prefix_len, statbuf->st_ctime);
+ out_string (pformat, prefix_len, epoch_time (get_stat_ctime (statbuf)));
break;
case 'C':
fail |= out_file_context (filename, pformat, prefix_len);
diff --git a/tests/touch/60-seconds b/tests/touch/60-seconds
index f858a30..f98f0c5 100755
--- a/tests/touch/60-seconds
+++ b/tests/touch/60-seconds
@@ -23,7 +23,7 @@ fi
. $srcdir/test-lib.sh
-echo 60 > exp || framework_failure
+echo 60.000000000 > exp || framework_failure
# Before coreutils-7.7, this would fail, complaining of
--
1.7.2.3
- [coreutils] [PATCH 2/2] stat: print timestamps to full resolution,
Eric Blake <=