[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolutio
From: |
Jim Meyering |
Subject: |
Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution |
Date: |
Thu, 21 Oct 2010 16:01:21 +0200 |
Andreas Schwab wrote:
> Jim Meyering <address@hidden> writes:
>
>> And besides, with coreutils-8.6 already released, reverting the
>> change is no longer an option.
>
> Why? I'm pretty sure more breakage will pop up over time.
Hmm... I see what you mean.
Anyone using a distribution with coreutils-8.5 or older will
think it's fine to treat $(stat -c %X) as an integer with no
decimal or trailing fraction.
Is it worthwhile to create a new format, say %...:X (and same for Y and Z)
that expands to seconds.nanoseconds and to revert %...X to the old
seconds-only semantics?
That would make it so people could use stat's %X %Y %Z portably
while new scripts can still get nanosecond accuracy when needed.
Here's PoC code:
$ for i in %X %:X %Y %:Y %Z %:Z; do src/stat -c $i .; done
1256665918
1256665918.441784225
1287476685
1287476685.450022280
1287476685
1287476685.450022280
In retrospect, %W should get the same treatment.
diff --git a/src/stat.c b/src/stat.c
index fabbc17..dfb4dcb 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -463,7 +463,7 @@ human_time (struct timespec t)
}
static char * ATTRIBUTE_WARN_UNUSED_RESULT
-epoch_time (struct timespec t)
+epoch_time (bool print_ns, struct timespec t)
{
static char str[INT_STRLEN_BOUND (time_t) + sizeof ".NNNNNNNNN"];
/* Note that time_t can technically be a floating point value, such
@@ -475,10 +475,20 @@ epoch_time (struct timespec t)
converting to struct tm just to use nstrftime (str, len, "%s.%N",
tm, 0, t.tv_nsec) is pointless, since nstrftime would have to
convert back to seconds as time_t. */
- if (TYPE_SIGNED (time_t))
- sprintf (str, "%" PRIdMAX ".%09ld", (intmax_t) t.tv_sec, t.tv_nsec);
+ if (print_ns)
+ {
+ if (TYPE_SIGNED (time_t))
+ sprintf (str, "%" PRIdMAX ".%09ld", (intmax_t) t.tv_sec, t.tv_nsec);
+ else
+ sprintf (str, "%" PRIuMAX ".%09ld", (uintmax_t) t.tv_sec, t.tv_nsec);
+ }
else
- sprintf (str, "%" PRIuMAX ".%09ld", (uintmax_t) t.tv_sec, t.tv_nsec);
+ {
+ if (TYPE_SIGNED (time_t))
+ sprintf (str, "%" PRIdMAX, (intmax_t) t.tv_sec);
+ else
+ sprintf (str, "%" PRIuMAX, (uintmax_t) t.tv_sec);
+ }
return str;
}
@@ -539,7 +549,8 @@ out_file_context (char *pformat, size_t prefix_len, char
const *filename)
/* Print statfs info. Return zero upon success, nonzero upon failure. */
static bool ATTRIBUTE_WARN_UNUSED_RESULT
-print_statfs (char *pformat, size_t prefix_len, char m, char const *filename,
+print_statfs (char *pformat, size_t prefix_len, unsigned int m,
+ char const *filename,
void const *data)
{
STRUCT_STATVFS const *statfsbuf = data;
@@ -713,7 +724,7 @@ print_mount_point:
/* Print stat info. Return zero upon success, nonzero upon failure. */
static bool
-print_stat (char *pformat, size_t prefix_len, char m,
+print_stat (char *pformat, size_t prefix_len, unsigned int m,
char const *filename, void const *data)
{
struct stat *statbuf = (struct stat *) data;
@@ -820,26 +831,35 @@ print_stat (char *pformat, size_t prefix_len, char m,
if (t.tv_nsec < 0)
out_string (pformat, prefix_len, "-");
else
- out_string (pformat, prefix_len, epoch_time (t));
+ out_string (pformat, prefix_len, epoch_time (0, t));
}
break;
case 'x':
out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
break;
case 'X':
- out_string (pformat, prefix_len, epoch_time (get_stat_atime (statbuf)));
+ out_string (pformat, prefix_len, epoch_time (0, get_stat_atime
(statbuf)));
+ break;
+ case 'X' + 256:
+ out_string (pformat, prefix_len, epoch_time (1, get_stat_atime
(statbuf)));
break;
case 'y':
out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf)));
break;
case 'Y':
- out_string (pformat, prefix_len, epoch_time (get_stat_mtime (statbuf)));
+ out_string (pformat, prefix_len, epoch_time (0, get_stat_mtime
(statbuf)));
+ break;
+ case 'Y' + 256:
+ out_string (pformat, prefix_len, epoch_time (1, get_stat_mtime
(statbuf)));
break;
case 'z':
out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf)));
break;
case 'Z':
- out_string (pformat, prefix_len, epoch_time (get_stat_ctime (statbuf)));
+ out_string (pformat, prefix_len, epoch_time (0, get_stat_ctime
(statbuf)));
+ break;
+ case 'Z' + 256:
+ out_string (pformat, prefix_len, epoch_time (1, get_stat_ctime
(statbuf)));
break;
case 'C':
fail |= out_file_context (pformat, prefix_len, filename);
@@ -897,7 +917,8 @@ print_esc_char (char c)
Return zero upon success, nonzero upon failure. */
static bool ATTRIBUTE_WARN_UNUSED_RESULT
print_it (char const *format, char const *filename,
- bool (*print_func) (char *, size_t, char, char const *, void const
*),
+ bool (*print_func) (char *, size_t, unsigned int,
+ char const *, void const *),
void const *data)
{
bool fail = false;
@@ -922,10 +943,21 @@ print_it (char const *format, char const *filename,
{
size_t len = strspn (b + 1, "#-+.I 0123456789");
char const *fmt_char = b + len + 1;
+ unsigned int fmt_code;
memcpy (dest, b, len + 1);
+ if (*fmt_char == ':' && strchr ("XYZ", fmt_char[1]))
+ {
+ fmt_code = fmt_char[1] + 256;
+ ++fmt_char;
+ }
+ else
+ {
+ fmt_code = fmt_char[0];
+ }
+
b = fmt_char;
- switch (*fmt_char)
+ switch (fmt_code)
{
case '\0':
--b;
@@ -941,7 +973,7 @@ print_it (char const *format, char const *filename,
putchar ('%');
break;
default:
- fail |= print_func (dest, len + 1, *fmt_char, filename, data);
+ fail |= print_func (dest, len + 1, fmt_code, filename, data);
break;
}
break;
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, (continued)
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Andreas Schwab, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Eric Blake, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Andreas Schwab, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Eric Blake, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Jim Meyering, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Jim Meyering, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Eric Blake, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Jim Meyering, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Jim Meyering, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Eric Blake, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution,
Jim Meyering <=
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Pádraig Brady, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Pádraig Brady, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Eric Blake, 2010/10/21
- Re: [coreutils] Re: [PATCH 2/2] stat: print timestamps to full resolution, Pádraig Brady, 2010/10/21