Package: coreutils;
Reported by: Jim Meyering <jim <at> meyering.net>
Date: Wed, 3 Nov 2010 18:56:02 UTC
Severity: normal
Done: Pádraig Brady <P <at> draigBrady.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 7325 in the body.
You can then email your comments to 7325 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 18:56:02 GMT) Full text and rfc822 format available.Jim Meyering <jim <at> meyering.net>
:bug-coreutils <at> gnu.org
.
(Wed, 03 Nov 2010 18:56:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: bug-coreutils <at> gnu.org Subject: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 19:59:44 +0100
At least on Solaris 10, the new stat-nanoseconds test fails, due to non-portability of snprintf vs a format like %010.3s: FAIL: misc/stat-nanoseconds ... + touch -d '2010-10-21 18:43:33.023456789' k ... ++ stat -c %05.3:X k + test 00023 = ' 023' + fail=1 You can demonstrate it with bash's built-in printf, too: solaris$ bash -c "printf '%010.3s\n' 23" 0000000023 glibc$ bash -c "printf '%010.3s\n' 23" 23 Note that coreutils' printf does not accept the '0' modifier in a %s format. $ env printf '%05.3s\n' 23 printf: %05.3s: invalid conversion specification That's because POSIX says the "0" modifier applies only to the d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers. One solution is to trim off the "0". It's probably a good idea regardless, in case some implementation rejects it. On the other hand, I find the zero-padding you currently get with stat on solaris to be slightly more intuitive. I'll sleep on it. Other opinions welcome, as usual.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 19:24:01 GMT) Full text and rfc822 format available.Message #8 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Eric Blake <eblake <at> redhat.com> To: Jim Meyering <jim <at> meyering.net> Cc: 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 13:27:45 -0600
[Message part 1 (text/plain, inline)]
On 11/03/2010 12:59 PM, Jim Meyering wrote: > Note that coreutils' printf does not accept the '0' modifier in a %s format. > > $ env printf '%05.3s\n' 23 > printf: %05.3s: invalid conversion specification > > That's because POSIX says the "0" modifier applies only to the > d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers. > > One solution is to trim off the "0". > It's probably a good idea regardless, in case some implementation rejects it. > > On the other hand, I find the zero-padding you currently get > with stat on solaris to be slightly more intuitive. I agree that %05.3:X resulting in 00023 would be ideal. And I agree that we'd have to trim off the 0 modifier before calling the underlying printf %s, and thus be responsible for putting in '0' padding ourselves rather than relying on printf() padding. -- Eric Blake eblake <at> redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
[signature.asc (application/pgp-signature, attachment)]
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 21:23:01 GMT) Full text and rfc822 format available.Message #11 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Eric Blake <eblake <at> redhat.com> Cc: 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 22:26:40 +0100
Eric Blake wrote: > On 11/03/2010 12:59 PM, Jim Meyering wrote: >> Note that coreutils' printf does not accept the '0' modifier in a %s format. >> >> $ env printf '%05.3s\n' 23 >> printf: %05.3s: invalid conversion specification >> >> That's because POSIX says the "0" modifier applies only to the >> d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers. >> >> One solution is to trim off the "0". >> It's probably a good idea regardless, in case some implementation rejects it. >> >> On the other hand, I find the zero-padding you currently get >> with stat on solaris to be slightly more intuitive. > > I agree that %05.3:X resulting in 00023 would be ideal. And I agree > that we'd have to trim off the 0 modifier before calling the underlying > printf %s, and thus be responsible for putting in '0' padding ourselves > rather than relying on printf() padding. Thanks for confirming. Here's the patch I'm considering: diff --git a/src/stat.c b/src/stat.c index d05a93b..993db48 100644 --- a/src/stat.c +++ b/src/stat.c @@ -472,6 +472,23 @@ epoch_sec (struct timespec t) return timetostr (t.tv_sec, str); } +/* Convert a LEN-byte FORMAT modifier, e.g., "0009.4", to "9.4". + Do it in place and return the new length. */ +static size_t +sanitize_format_string (char *format, size_t len) +{ + char *p = format; + char const *end = format + len; + while (p < end && *p == '0') + p++; + if (p == format) + return len; + + len -= p - format; + memmove (format, p, len); + return len; +} + /* Output the number of nanoseconds, ARG.tv_nsec, honoring a WIDTH.PRECISION format modifier, where PRECISION specifies how many leading digits(on a field of 9) to print. */ @@ -496,8 +513,25 @@ out_ns (char *pformat, size_t prefix_len, struct timespec arg) { char tmp[INT_BUFSIZE_BOUND (uintmax_t)]; snprintf (tmp, sizeof tmp, "%09lu", ns); + /* Handle formats like %5.3:X and %05.3:X, which, with the likes of + "023" in TMP, should print " 023" and "00023" respectively. + Do not use a format like "%05s" with *printf, since POSIX says + the '0' modifier does not apply to the "s" conversion specifier. */ + size_t new_len = sanitize_format_string (pformat + 1, prefix_len - 1); + bool zero_pad = (new_len < prefix_len - 1); + prefix_len = new_len + 1; strcpy (pformat + prefix_len, "s"); - printf (pformat, tmp); + char b2[INT_BUFSIZE_BOUND (uintmax_t)]; + /* Format the result, as usual... */ + snprintf (b2, sizeof b2, pformat, tmp); + /* But if zero-padding is desired, convert leading blanks to zeros. */ + if (zero_pad) + { + char *p = b2; + while (*p == ' ') + *p++ = '0'; + } + fputs (b2, stdout); } else { diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds index 314f43e..9c06a51 100755 --- a/tests/misc/stat-nanoseconds +++ b/tests/misc/stat-nanoseconds @@ -30,7 +30,7 @@ test "$(stat -c %3.3:X k)" = 023 || fail=1 test "$(stat -c %.3:X k)" = 023 || fail=1 test "$(stat -c %03.3:X k)" = 023 || fail=1 test "$(stat -c %-5.3:X k)" = '023 ' || fail=1 -test "$(stat -c %05.3:X k)" = ' 023' || fail=1 -test "$(stat -c %010.3:X k)" = ' 023' || fail=1 +test "$(stat -c %05.3:X k)" = 00023 || fail=1 +test "$(stat -c %010.3:X k)" = 0000000023 || fail=1 Exit $fail
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 21:29:01 GMT) Full text and rfc822 format available.Message #14 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Eric Blake <eblake <at> redhat.com> To: Jim Meyering <jim <at> meyering.net> Cc: 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 15:32:55 -0600
[Message part 1 (text/plain, inline)]
On 11/03/2010 03:26 PM, Jim Meyering wrote: >> I agree that %05.3:X resulting in 00023 would be ideal. And I agree >> that we'd have to trim off the 0 modifier before calling the underlying >> printf %s, and thus be responsible for putting in '0' padding ourselves >> rather than relying on printf() padding. > > Thanks for confirming. > Here's the patch I'm considering: > > diff --git a/src/stat.c b/src/stat.c > index d05a93b..993db48 100644 > --- a/src/stat.c > +++ b/src/stat.c > @@ -472,6 +472,23 @@ epoch_sec (struct timespec t) > return timetostr (t.tv_sec, str); > } > > +/* Convert a LEN-byte FORMAT modifier, e.g., "0009.4", to "9.4". > + Do it in place and return the new length. */ > +static size_t > +sanitize_format_string (char *format, size_t len) > +{ > + char *p = format; > + char const *end = format + len; > + while (p < end && *p == '0') > + p++; > + if (p == format) > + return len; > + > + len -= p - format; > + memmove (format, p, len); > + return len; > +} Not just leading zeros. Think also about "%-0 010.4:X", which must sanitize to "%- 10.4s" - that is, you must strip any zero until the first non-zero digit or '.' is found. -- Eric Blake eblake <at> redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
[signature.asc (application/pgp-signature, attachment)]
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 22:55:02 GMT) Full text and rfc822 format available.Message #17 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 15:58:25 -0700
The test-case part of that looks OK, but the change to stat.c can be simplified. Also, there's a similar problem with a format like %020X, which should be fixed too. While we're on the subject, there are other ways that stat invokers can exercise undefined behavior (in the C sense) by passing weird formats in. This really should get fixed at some point. The patch proposed below addresses just the immediate issue. From a24a9ce8f3711670a6413c60b5e9ebd3e51a4e06 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert <at> cs.ucla.edu> Date: Wed, 3 Nov 2010 15:49:50 -0700 Subject: [PATCH] stat: handle leading '0' when formatting secs and ns * src/stat.c (epoch_sec): Remove. All callers changed to use out_epoch_sec instead. (out_ns): Use numeric format, not string format, to output the nanoseconds count; this avoids unportable use of (e.g.) %05s in a printf format. (out_epoch_sec): New function. This also uses a numeric format, instead of a string format, to output a number. --- src/stat.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/stat.c b/src/stat.c index d05a93b..c1def13 100644 --- a/src/stat.c +++ b/src/stat.c @@ -463,15 +463,6 @@ human_time (struct timespec t) return str; } -/* Return a string representation (in static storage) - of the number of seconds in T since the epoch. */ -static char * ATTRIBUTE_WARN_UNUSED_RESULT -epoch_sec (struct timespec t) -{ - static char str[INT_BUFSIZE_BOUND (time_t)]; - return timetostr (t.tv_sec, str); -} - /* Output the number of nanoseconds, ARG.tv_nsec, honoring a WIDTH.PRECISION format modifier, where PRECISION specifies how many leading digits(on a field of 9) to print. */ @@ -491,13 +482,29 @@ out_ns (char *pformat, size_t prefix_len, struct timespec arg) on the default representation, i.e., a zero padded number of width 9. */ unsigned long int ns = arg.tv_nsec; + char *dot = memchr (pformat, '.', prefix_len); - if (memchr (pformat, '.', prefix_len)) /* precision specified. */ + if (dot) { - char tmp[INT_BUFSIZE_BOUND (uintmax_t)]; - snprintf (tmp, sizeof tmp, "%09lu", ns); - strcpy (pformat + prefix_len, "s"); - printf (pformat, tmp); + /* Precision specified. */ + size_t i; + int precision = 0; + for (i = dot - pformat + 1; i < prefix_len && ISDIGIT (pformat[i]); i++) + { + if (! precision) + precision = pformat[i] - '0'; + else + { + /* If more than 9 digits are asked for, just output 9. */ + precision = 9; + break; + } + } + if (! precision) + return; + for (; precision < 9; precision++) + ns /= 10; + strcpy (dot, "lu"); } else { @@ -505,8 +512,9 @@ out_ns (char *pformat, size_t prefix_len, struct timespec arg) /* Note that pformat is big enough, as %:X -> %09lu and two extra bytes are already allocated. */ strcpy (pformat + prefix_len, fmt); - printf (pformat, ns); } + + printf (pformat, ns); } static void @@ -539,6 +547,14 @@ out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) strcpy (pformat + prefix_len, PRIxMAX); printf (pformat, arg); } +static void +out_epoch_sec (char *pformat, size_t prefix_len, struct timespec arg) +{ + if (TYPE_SIGNED (time_t)) + out_int (pformat, prefix_len, arg.tv_sec); + else + out_uint (pformat, prefix_len, arg.tv_sec); +} /* Print the context information of FILENAME, and return true iff the context could not be obtained. */ @@ -853,8 +869,8 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, } break; case 'W': - out_string (pformat, prefix_len, - epoch_sec (neg_to_zero (get_stat_birthtime (statbuf)))); + out_epoch_sec (pformat, prefix_len, + neg_to_zero (get_stat_birthtime (statbuf))); break; case 'W' + 256: out_ns (pformat, prefix_len, neg_to_zero (get_stat_birthtime (statbuf))); @@ -863,7 +879,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); break; case 'X': - out_string (pformat, prefix_len, epoch_sec (get_stat_atime (statbuf))); + out_epoch_sec (pformat, prefix_len, get_stat_atime (statbuf)); break; case 'X' + 256: out_ns (pformat, prefix_len, get_stat_atime (statbuf)); @@ -872,7 +888,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); break; case 'Y': - out_string (pformat, prefix_len, epoch_sec (get_stat_mtime (statbuf))); + out_epoch_sec (pformat, prefix_len, get_stat_mtime (statbuf)); break; case 'Y' + 256: out_ns (pformat, prefix_len, get_stat_mtime (statbuf)); @@ -881,7 +897,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); break; case 'Z': - out_string (pformat, prefix_len, epoch_sec (get_stat_ctime (statbuf))); + out_epoch_sec (pformat, prefix_len, get_stat_ctime (statbuf)); break; case 'Z' + 256: out_ns (pformat, prefix_len, get_stat_ctime (statbuf)); -- 1.7.2
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 03 Nov 2010 23:39:01 GMT) Full text and rfc822 format available.Message #20 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Eric Blake <eblake <at> redhat.com> Cc: 7325 <at> debbugs.gnu.org, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 03 Nov 2010 23:42:44 +0000
On 03/11/10 19:27, Eric Blake wrote: > On 11/03/2010 12:59 PM, Jim Meyering wrote: >> Note that coreutils' printf does not accept the '0' modifier in a %s format. >> >> $ env printf '%05.3s\n' 23 >> printf: %05.3s: invalid conversion specification >> >> That's because POSIX says the "0" modifier applies only to the >> d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers. >> >> One solution is to trim off the "0". >> It's probably a good idea regardless, in case some implementation rejects it. >> >> On the other hand, I find the zero-padding you currently get >> with stat on solaris to be slightly more intuitive. > > I agree that %05.3:X resulting in 00023 would be ideal. I disagree because I can't see how that's useful. The above is for 023xxxxxx nanoseconds. So what is 23 in that context? > And I agree that we'd have to trim off the 0 modifier before calling the underlying > printf %s, and thus be responsible for putting in '0' padding ourselves > rather than relying on printf() padding. > I'd just strip any leading 0 if a precision is specified, to suppress the problematic solaris behavior. cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 04 Nov 2010 07:29:02 GMT) Full text and rfc822 format available.Message #23 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 04 Nov 2010 08:32:32 +0100
Pádraig Brady wrote: > On 03/11/10 19:27, Eric Blake wrote: >> On 11/03/2010 12:59 PM, Jim Meyering wrote: >>> Note that coreutils' printf does not accept the '0' modifier in a %s format. >>> >>> $ env printf '%05.3s\n' 23 >>> printf: %05.3s: invalid conversion specification >>> >>> That's because POSIX says the "0" modifier applies only to the >>> d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers. >>> >>> One solution is to trim off the "0". >>> It's probably a good idea regardless, in case some implementation rejects it. >>> >>> On the other hand, I find the zero-padding you currently get >>> with stat on solaris to be slightly more intuitive. >> >> I agree that %05.3:X resulting in 00023 would be ideal. > > I disagree because I can't see how that's useful. > The above is for 023xxxxxx nanoseconds. > So what is 23 in that context? The reason I prefer the above is that (regardless of semantics) it is consistent with what one would expect of a numeric conversion specifier. That means no surprises for the user who knows about printf and no need to document anything different about how stat's %[WXYZ] specifiers work.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 04 Nov 2010 07:33:02 GMT) Full text and rfc822 format available.Message #26 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 04 Nov 2010 08:37:00 +0100
Paul Eggert wrote: > The test-case part of that looks OK, but the change to stat.c > can be simplified. Also, there's a similar problem with a format > like %020X, which should be fixed too. > > While we're on the subject, there are other ways that stat invokers > can exercise undefined behavior (in the C sense) by passing > weird formats in. This really should get fixed at some point. > The patch proposed below addresses just the immediate issue. > >>From a24a9ce8f3711670a6413c60b5e9ebd3e51a4e06 Mon Sep 17 00:00:00 2001 > From: Paul Eggert <eggert <at> cs.ucla.edu> > Date: Wed, 3 Nov 2010 15:49:50 -0700 > Subject: [PATCH] stat: handle leading '0' when formatting secs and ns > > * src/stat.c (epoch_sec): Remove. All callers changed to use > out_epoch_sec instead. > (out_ns): Use numeric format, not string format, to output > the nanoseconds count; this avoids unportable use of (e.g.) > %05s in a printf format. > (out_epoch_sec): New function. This also uses a numeric format, > instead of a string format, to output a number. Thanks! I like it. FYI, I need slightly different tests for that, so am amending with these: diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds index 314f43e..44862eb 100755 --- a/tests/misc/stat-nanoseconds +++ b/tests/misc/stat-nanoseconds @@ -26,11 +26,11 @@ ls --full-time | grep 18:43:33.023456789 \ test "$(stat -c %:X k)" = 023456789 || fail=1 test "$(stat -c %3:X k)" = 23456789 || fail=1 -test "$(stat -c %3.3:X k)" = 023 || fail=1 -test "$(stat -c %.3:X k)" = 023 || fail=1 +test "$(stat -c %3.3:X k)" = ' 23' || fail=1 +test "$(stat -c %.3:X k)" = 23 || fail=1 test "$(stat -c %03.3:X k)" = 023 || fail=1 -test "$(stat -c %-5.3:X k)" = '023 ' || fail=1 -test "$(stat -c %05.3:X k)" = ' 023' || fail=1 -test "$(stat -c %010.3:X k)" = ' 023' || fail=1 +test "$(stat -c %-5.3:X k)" = '23 ' || fail=1 +test "$(stat -c %05.3:X k)" = 00023 || fail=1 +test "$(stat -c %010.3:X k)" = 0000000023 || fail=1 Exit $fail
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 04 Nov 2010 07:53:02 GMT) Full text and rfc822 format available.Message #29 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 04 Nov 2010 08:56:54 +0100
Paul Eggert wrote: > The test-case part of that looks OK, but the change to stat.c > can be simplified. Also, there's a similar problem with a format > like %020X, which should be fixed too. > > While we're on the subject, there are other ways that stat invokers > can exercise undefined behavior (in the C sense) by passing > weird formats in. This really should get fixed at some point. > The patch proposed below addresses just the immediate issue. > >>From a24a9ce8f3711670a6413c60b5e9ebd3e51a4e06 Mon Sep 17 00:00:00 2001 > From: Paul Eggert <eggert <at> cs.ucla.edu> > Date: Wed, 3 Nov 2010 15:49:50 -0700 > Subject: [PATCH] stat: handle leading '0' when formatting secs and ns > > * src/stat.c (epoch_sec): Remove. All callers changed to use > out_epoch_sec instead. > (out_ns): Use numeric format, not string format, to output > the nanoseconds count; this avoids unportable use of (e.g.) > %05s in a printf format. > (out_epoch_sec): New function. This also uses a numeric format, > instead of a string format, to output a number. However, what about Eric's example? $ src/stat-p -c '_%-0 010.4:X_' k # yours _234 _ $ src/stat-j -c '_%-0 010.4:X_' k # mine _0234 _ and printf (note how it includes the leading space): $ env printf '_%-0 010.4d_\n' 234 _ 0234 _
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 04 Nov 2010 20:06:02 GMT) Full text and rfc822 format available.Message #32 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 04 Nov 2010 13:10:04 -0700
On 11/04/10 00:56, Jim Meyering wrote: > However, what about Eric's example? > > $ src/stat-p -c '_%-0 010.4:X_' k # yours > _234 _ > $ src/stat-j -c '_%-0 010.4:X_' k # mine > _0234 _ That's simply an issue of whether the value is considered to be signed or unsigned, and can be fixed by the patch at the end of this message. However, let me take a step back a minute. Do users really want all this functionality? Personally, what I'd like to see is a single format like this: %.3X that prints out the entire seconds since the Epoch, truncated to millseconds. That's simpler than what we require now: %X.%.3:X The changelogs suggest that we used to do things the simpler way, but changed on Oct. 21. I don't recall this being discussed: I assume it was due to floating point rounding issues. Still, I'd prefer the simpler notation, and we should be able to implement it without floating point. Would that be OK? The idea would be to support ".PRECISION" in the formats for W, X, Y, and Z, and to drop support for ':W' and the like. From 1dc473cc61099d5a1bf6bc26358bafd81cd670bd Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert <at> cs.ucla.edu> Date: Thu, 4 Nov 2010 12:56:17 -0700 Subject: [PATCH] * src/stat.c (out_ns): Treat the ns value as being signed. --- src/stat.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stat.c b/src/stat.c index c1def13..dd352a4 100644 --- a/src/stat.c +++ b/src/stat.c @@ -481,7 +481,7 @@ out_ns (char *pformat, size_t prefix_len, struct timespec arg) in the modifier, then then treat the modifier as operating on the default representation, i.e., a zero padded number of width 9. */ - unsigned long int ns = arg.tv_nsec; + long int ns = arg.tv_nsec; char *dot = memchr (pformat, '.', prefix_len); if (dot) @@ -504,12 +504,12 @@ out_ns (char *pformat, size_t prefix_len, struct timespec arg) return; for (; precision < 9; precision++) ns /= 10; - strcpy (dot, "lu"); + strcpy (dot, "ld"); } else { - char const *fmt = (prefix_len == 1) ? "09lu" : "lu"; - /* Note that pformat is big enough, as %:X -> %09lu + char const *fmt = (prefix_len == 1) ? "09ld" : "ld"; + /* Note that pformat is big enough, as %:X -> %09ld and two extra bytes are already allocated. */ strcpy (pformat + prefix_len, fmt); } -- 1.7.2
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 04 Nov 2010 20:39:01 GMT) Full text and rfc822 format available.Message #35 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 04 Nov 2010 21:42:29 +0100
Paul Eggert wrote: > On 11/04/10 00:56, Jim Meyering wrote: > >> However, what about Eric's example? >> >> $ src/stat-p -c '_%-0 010.4:X_' k # yours >> _234 _ >> $ src/stat-j -c '_%-0 010.4:X_' k # mine >> _0234 _ > > That's simply an issue of whether the value is considered to be signed > or unsigned, and can be fixed by the patch at the end of this message. > > However, let me take a step back a minute. Do users really want all > this functionality? Personally, what I'd like to see is a single > format like this: > > %.3X > > that prints out the entire seconds since the Epoch, truncated > to millseconds. That's simpler than what we require now: > > %X.%.3:X > > The changelogs suggest that we used to do things the simpler way, > but changed on Oct. 21. I don't recall this being discussed: I It was due to portability concerns, since with coreutils-8.6, %X, %Y, etc. expanded to floating point values, and that broke backwards compatibility: http://thread.gmane.org/gmane.comp.gnu.coreutils.general/161/focus=366 However, enabling floating point output only when there is a ".PREC" part of the format sounds like a fine compromise. Sure, old scripts that used %.3X (expecting no ".") would break, but I doubt any such uses exist, since that notation did nothing useful. A patch would be most welcome. > assume it was due to floating point rounding issues. Still, I'd > prefer the simpler notation, and we should be able to implement it > without floating point. Would that be OK? The idea would be > to support ".PRECISION" in the formats for W, X, Y, and Z, and > to drop support for ':W' and the like.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 05 Nov 2010 01:02:02 GMT) Full text and rfc822 format available.Message #38 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 05 Nov 2010 01:05:32 +0000
On 04/11/10 20:10, Paul Eggert wrote: > On 11/04/10 00:56, Jim Meyering wrote: > >> However, what about Eric's example? >> >> $ src/stat-p -c '_%-0 010.4:X_' k # yours >> _234 _ >> $ src/stat-j -c '_%-0 010.4:X_' k # mine >> _0234 _ > > That's simply an issue of whether the value is considered to be signed > or unsigned, and can be fixed by the patch at the end of this message. > > However, let me take a step back a minute. Do users really want all > this functionality? Personally, what I'd like to see is a single > format like this: > > %.3X > > that prints out the entire seconds since the Epoch, truncated > to millseconds. That's simpler than what we require now: > > %X.%.3:X > > The changelogs suggest that we used to do things the simpler way, > but changed on Oct. 21. I don't recall this being discussed: I > assume it was due to floating point rounding issues. Still, I'd > prefer the simpler notation, and we should be able to implement it > without floating point. Would that be OK? The idea would be > to support ".PRECISION" in the formats for W, X, Y, and Z, and > to drop support for ':W' and the like. I think you're echoing my suggestion here: http://comments.gmane.org/gmane.comp.gnu.coreutils.general/369 Given the counter arguments there it was decided to split to X and :X etc. I still slightly prefer just using %.X as it's backwards compat with older coreutils (excluding 8.6). cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 05 Nov 2010 06:30:03 GMT) Full text and rfc822 format available.Message #41 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Eric Blake <eblake <at> redhat.com>, Paul Eggert <eggert <at> cs.ucla.edu>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 05 Nov 2010 07:34:25 +0100
Pádraig Brady wrote: ... >> That's simply an issue of whether the value is considered to be signed >> or unsigned, and can be fixed by the patch at the end of this message. >> >> However, let me take a step back a minute. Do users really want all >> this functionality? Personally, what I'd like to see is a single >> format like this: >> >> %.3X >> >> that prints out the entire seconds since the Epoch, truncated >> to millseconds. That's simpler than what we require now: >> >> %X.%.3:X >> >> The changelogs suggest that we used to do things the simpler way, >> but changed on Oct. 21. I don't recall this being discussed: I >> assume it was due to floating point rounding issues. Still, I'd >> prefer the simpler notation, and we should be able to implement it >> without floating point. Would that be OK? The idea would be >> to support ".PRECISION" in the formats for W, X, Y, and Z, and >> to drop support for ':W' and the like. > > I think you're echoing my suggestion here: > http://comments.gmane.org/gmane.comp.gnu.coreutils.general/369 Oh! Indeed. Sorry I didn't see that part of the thread. > Given the counter arguments there it was decided to > split to X and :X etc. > > I still slightly prefer just using %.X as > it's backwards compat with older coreutils (excluding 8.6). So do I.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 05 Nov 2010 18:30:02 GMT) Full text and rfc822 format available.Message #44 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 05 Nov 2010 19:34:07 +0100
Jim Meyering wrote: > Paul Eggert wrote: >> On 11/04/10 00:56, Jim Meyering wrote: >> >>> However, what about Eric's example? >>> >>> $ src/stat-p -c '_%-0 010.4:X_' k # yours >>> _234 _ >>> $ src/stat-j -c '_%-0 010.4:X_' k # mine >>> _0234 _ >> >> That's simply an issue of whether the value is considered to be signed >> or unsigned, and can be fixed by the patch at the end of this message. >> >> However, let me take a step back a minute. Do users really want all >> this functionality? Personally, what I'd like to see is a single >> format like this: >> >> %.3X >> >> that prints out the entire seconds since the Epoch, truncated >> to millseconds. That's simpler than what we require now: >> >> %X.%.3:X >> >> The changelogs suggest that we used to do things the simpler way, >> but changed on Oct. 21. I don't recall this being discussed: I > > It was due to portability concerns, since with coreutils-8.6, > %X, %Y, etc. expanded to floating point values, and that broke > backwards compatibility: > > http://thread.gmane.org/gmane.comp.gnu.coreutils.general/161/focus=366 > > However, enabling floating point output only when there is a ".PREC" > part of the format sounds like a fine compromise. > Sure, old scripts that used %.3X (expecting no ".") would break, > but I doubt any such uses exist, since that notation did nothing useful. > > A patch would be most welcome. Hi Paul, Please let us know whether you are working on this.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 06 Nov 2010 02:27:02 GMT) Full text and rfc822 format available.Message #47 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 05 Nov 2010 19:31:03 -0700
On 11/05/2010 11:34 AM, Jim Meyering wrote: > Please let us know whether you are working on this. Yes I am. (So hard that I wasn't reading my email. :-) Please expect a patch soon, but it won't be tiny.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 06 Nov 2010 02:51:01 GMT) Full text and rfc822 format available.Message #50 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 05 Nov 2010 19:54:28 -0700
On 11/04/2010 11:34 PM, Jim Meyering wrote: > Pádraig Brady wrote: >> I still slightly prefer just using %.X as >> it's backwards compat with older coreutils (excluding 8.6). > > So do I. I built that and tried it out, and found another problem that has been annoying me for years in other programs: 'stat' prints out unnecessary trailing zeros for time stamps, when the file system resolution is coarser than nanosecond resolution. So I figured I'd fix that too, for 'stat' (other programs can be fixed later). With this fix, %.X outputs the time stamp but omits trailing zeros if it can infer that the file system would always put zeros there. If you want a specific number of zeros, you can use something like %.3X or %.9X (or %.100X :-). From d37bad3d644a98887402b5398b7280701a7b7559 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert <at> cs.ucla.edu> Date: Fri, 5 Nov 2010 19:35:12 -0700 Subject: [PATCH] stat: use e.g. %.3X instead of %X.%3:X for sub-second precision * NEWS: Document this. * doc/coreutils.texi (stat invocation): Likewise. * gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec: * gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c: New files. * bootstrap.conf (gnulib_modules): Add fstimeprec. * src/stat.c: Include fstimeprec.h. Don't include xstrtol.h. (decimal_point, decimal_point_len): New static vars. (main): Initialize them. (epoch_sec, out_ns): Remove. (out_int, out_uint): Now returns whatever printf returned. (out_minus_zero, out_epoch_secs): New functions. (print_stat): Use out_epoch_sec instead of out_ns and epoch_sec. (print_stat, print_it, usage): Remove the %:X-style formats. * tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems with weird time zones. Use a time stamp near the Epoch so that we don't have to worry about leap seconds. Redo test cases to match new behavior. * tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to new behavior. --- NEWS | 10 +-- bootstrap.conf | 1 + doc/coreutils.texi | 37 ++++---- gl/lib/fstimeprec.c | 178 +++++++++++++++++++++++++++++++++++ gl/lib/fstimeprec.h | 22 +++++ gl/modules/fstimeprec | 24 +++++ gl/modules/fstimeprec-tests | 10 ++ gl/tests/test-fstimeprec.c | 74 +++++++++++++++ src/stat.c | 218 ++++++++++++++++++++++++++----------------- tests/misc/stat-nanoseconds | 25 +++-- tests/touch/60-seconds | 2 +- 11 files changed, 480 insertions(+), 121 deletions(-) create mode 100644 gl/lib/fstimeprec.c create mode 100644 gl/lib/fstimeprec.h create mode 100644 gl/modules/fstimeprec create mode 100644 gl/modules/fstimeprec-tests create mode 100644 gl/tests/test-fstimeprec.c diff --git a/NEWS b/NEWS index 3b9bea2..1e5a8db 100644 --- a/NEWS +++ b/NEWS @@ -20,16 +20,12 @@ GNU coreutils NEWS -*- outline -*- stat's %X, %Y, and %Z directives once again print only the integer part of seconds since the epoch. This reverts a change from coreutils-8.6, that was deemed unnecessarily disruptive. To obtain - the nanoseconds portion corresponding to %X, you may now use %:X. - I.e., to print the floating point number of seconds using maximum - precision, use this format string: %X.%:X. Likewise for %Y, %Z and %W. + a full resolution time stamp for %X, use %.X; if you want (say) just + 3 fractional digits, use %.3X. Likewise for %Y and %Z. stat's new %W format directive would print floating point seconds. However, with the above change to %X, %Y and %Z, we've made %W work - the same way: %W now expands to seconds since the epoch (or 0 when - not supported), and %:W expands to the nanoseconds portion, or to - 0 if not supported. - + the same way as the others. * Noteworthy changes in release 8.6 (2010-10-15) [stable] diff --git a/bootstrap.conf b/bootstrap.conf index 18ef914..5a6ebae 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -85,6 +85,7 @@ gnulib_modules=" freopen freopen-safer fseeko + fstimeprec fsusage fsync ftello diff --git a/doc/coreutils.texi b/doc/coreutils.texi index be5999f..8dfb069 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10707,37 +10707,36 @@ The valid @var{format} directives for files with @option{--format} and @item %U - User name of owner @item %w - Time of file birth, or @samp{-} if unknown @item %W - Time of file birth as seconds since Epoch, or @samp{0} -@item %:W - Time of file birth: nanoseconds remainder, or @samp{0} @item %x - Time of last access @item %X - Time of last access as seconds since Epoch -@item %:X - Time of last access: nanoseconds remainder @item %y - Time of last modification @item %Y - Time of last modification as seconds since Epoch -@item %:Y - Time of last modification: nanoseconds remainder @item %z - Time of last change @item %Z - Time of last change as seconds since Epoch -@item %:Z - Time of last change: nanoseconds remainder @end itemize -Note that each of @samp{%:W}, @samp{%:X}, @samp{%:Y} and @samp{%:Z} -prints its zero-padded number of nanoseconds on a field of width 9. -However, if you specify anything between the @samp{%} and @samp{:}, -e.g., @samp{%10:X}, your modifier replaces the default of @samp{09}. - -Here are some examples: +The @samp{%W}, @samp{%X}, @samp{%Y}, and @samp{%Z} formats accept a +precision preceded by a period to specify the number of digits to +print after the decimal point. For example, @samp{%.9X} outputs the +last access time to nanosecond precision. If a period is given but no +precision, @command{stat} uses the estimated precision of the file +system. When discarding excess precision, time stamps are truncated +toward minus infinity. @example zero pad: - $ stat -c '[%015:Y]' /usr - [000000031367045] + $ stat -c '[%015Y]' /usr + [000001288929712] space align: - $ stat -c '[%15:Y]' /usr - [ 31367045] - $ stat -c '[%-15:Y]' /usr - [31367045 ] -truncate: - $ stat -c '[%.3:Y]' /usr - [031] + $ stat -c '[%15Y]' /usr + [ 1288929712] + $ stat -c '[%-15Y]' /usr + [1288929712 ] +precision: + $ stat -c '[%.3Y]' /usr + [1288929712.114] + $ stat -c '[%.Y]' /usr + [1288929712.114951] @end example The mount point printed by @samp{%m} is similar to that output diff --git a/gl/lib/fstimeprec.c b/gl/lib/fstimeprec.c new file mode 100644 index 0000000..fd63054 --- /dev/null +++ b/gl/lib/fstimeprec.c @@ -0,0 +1,178 @@ +/* Determine a file system's time stamp precision. + + Copyright 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* written by Paul Eggert */ + +#include <config.h> +#include "fstimeprec.h" + +#include "hash.h" +#include "stat-time.h" +#include <limits.h> +#include <stdlib.h> + +/* A hash table that maps device numbers to precisions. */ +struct fstimeprec +{ + /* Map device numbers to precisions. */ + struct hash_table *map; + + /* Cache of the most recently allocated and otherwise-unused storage + for probing this table. */ + struct ent *probe; +}; + +/* A pair that maps a device number to a precision. */ +struct ent +{ + dev_t dev; + int prec; +}; + +/* Hash an entry. */ +static size_t +ent_hash (void const *x, size_t table_size) +{ + struct ent const *p = x; + dev_t dev = p->dev; + + /* FIXME: This code is duplicated from di-set.c. */ + /* When DEV is wider than size_t, exclusive-OR the words of DEV into H. + This avoids loss of info, without applying % to the wider type, + which could be quite slow on some systems. */ + size_t h = dev; + unsigned int i; + unsigned int n_words = sizeof dev / sizeof h + (sizeof dev % sizeof h != 0); + for (i = 1; i < n_words; i++) + h ^= dev >> CHAR_BIT * sizeof h * i; + + return h % table_size; +} + +/* Return true if two entries are the same. */ +static bool +ent_compare (void const *x, void const *y) +{ + struct ent const *a = x; + struct ent const *b = y; + return a->dev == b->dev; +} + +/* Using the SET table, map a device to an entry that represents + the file system precision. Return NULL on error. */ +static struct ent * +map_device (struct fstimeprec *tab, dev_t dev) +{ + /* Find space for the probe, reusing the cache if available. */ + struct ent *ent; + struct ent *probe = tab->probe; + if (probe) + { + /* If repeating a recent query, return the cached result. */ + if (probe->dev == dev) + return probe; + } + else + { + tab->probe = probe = malloc (sizeof *probe); + if (! probe) + return NULL; + probe->prec = 0; + } + + /* Probe for the device. */ + probe->dev = dev; + ent = hash_insert (tab->map, probe); + if (ent == probe) + tab->probe = NULL; + return ent; +} + +/* Return a newly allocated table of file system time stamp + resolutions, or NULL if out of memory. */ +struct fstimeprec * +fstimeprec_alloc (void) +{ + struct fstimeprec *tab = malloc (sizeof *tab); + if (tab) + { + enum { INITIAL_DEV_MAP_SIZE = 11 }; + tab->map = hash_initialize (INITIAL_DEV_MAP_SIZE, NULL, + ent_hash, ent_compare, free); + if (! tab->map) + { + free (tab); + return NULL; + } + tab->probe = NULL; + } + return tab; +} + +/* Free TAB. */ +void +fstimeprec_free (struct fstimeprec *tab) +{ + hash_free (tab->map); + free (tab->probe); + free (tab); +} + +/* Using the cached information in TAB, return the estimated precision + of time stamps for the file system containing the file whose status + info is in ST. The returned value counts the number of decimal + fraction digits. Return 0 on failure. + + If TAB is null, the guess is based purely on ST. */ +int +fstimeprec (struct fstimeprec *tab, struct stat const *st) +{ + /* Map the device number to an entry. */ + struct ent *ent = (tab ? map_device (tab, st->st_dev) : NULL); + + /* Guess the precision based on what has been seen so far. */ + int prec = (ent ? ent->prec : 0); + + /* If the current file's timestamp resolution is higher than the + guess, increase the guess. */ + if (prec < 9) + { + struct timespec ats = get_stat_atime (st); + struct timespec mts = get_stat_mtime (st); + struct timespec cts = get_stat_ctime (st); + struct timespec bts = get_stat_birthtime (st); + unsigned int ans = ats.tv_nsec; + unsigned int mns = mts.tv_nsec; + unsigned int cns = cts.tv_nsec; + unsigned int bns = bts.tv_nsec < 0 ? 0 : bts.tv_nsec; + unsigned int power = 10; + int p; + for (p = prec + 1; p < 9; p++) + power *= 10; + + while (ans % power | mns % power | cns % power | bns % power) + { + power /= 10; + prec++; + } + + if (ent) + ent->prec = prec; + } + + return prec; +} diff --git a/gl/lib/fstimeprec.h b/gl/lib/fstimeprec.h new file mode 100644 index 0000000..8ec24df --- /dev/null +++ b/gl/lib/fstimeprec.h @@ -0,0 +1,22 @@ +#include <sys/stat.h> + +#ifndef ATTRIBUTE_MALLOC +# if __GNUC__ >= 3 +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define ATTRIBUTE_MALLOC +# endif +#endif + +#ifndef _GL_ARG_NONNULL +# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 +# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +# else +# define _GL_ARG_NONNULL(params) +# endif +#endif + +struct fstimeprec *fstimeprec_alloc (void) ATTRIBUTE_MALLOC; +void fstimeprec_free (struct fstimeprec *) _GL_ARG_NONNULL ((1)); +int fstimeprec (struct fstimeprec *, struct stat const *) + _GL_ARG_NONNULL ((2)); diff --git a/gl/modules/fstimeprec b/gl/modules/fstimeprec new file mode 100644 index 0000000..787c2e7 --- /dev/null +++ b/gl/modules/fstimeprec @@ -0,0 +1,24 @@ +Description: +estimate precision of time stamps in file systems + +Files: +lib/fstimeprec.c +lib/fstimeprec.h + +Depends-on: +hash +stat-time + +configure.ac: + +Makefile.am: +lib_SOURCES += fstimeprec.c fstimeprec.h + +Include: +"fstimeprec.h" + +License +GPL + +Maintainer: +Paul Eggert and Jim Meyering diff --git a/gl/modules/fstimeprec-tests b/gl/modules/fstimeprec-tests new file mode 100644 index 0000000..bf6b49e --- /dev/null +++ b/gl/modules/fstimeprec-tests @@ -0,0 +1,10 @@ +Files: +tests/test-fstimeprec.c + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-fstimeprec +check_PROGRAMS += test-fstimeprec diff --git a/gl/tests/test-fstimeprec.c b/gl/tests/test-fstimeprec.c new file mode 100644 index 0000000..f699139 --- /dev/null +++ b/gl/tests/test-fstimeprec.c @@ -0,0 +1,74 @@ +/* Test the fstimeprec module. + Copyright (C) 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* written by Paul Eggert */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/stat.h> + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +#include "fstimeprec.h" + +static int +fstimeprec_file (struct fstimeprec *tab, char const *file) +{ + struct stat st; + if (stat (file, &st) != 0) + return 0; + return fstimeprec (tab, &st); +} + +int +main (void) +{ + struct fstimeprec *tab = fstimeprec_alloc (); + ASSERT (tab); + + int m1 = fstimeprec_file (tab, "/"); + int m2 = fstimeprec_file (tab, "."); + int m3 = fstimeprec_file (tab, ".."); + ASSERT (0 <= m1 && m1 <= 9); + ASSERT (0 <= m2 && m2 <= 9); + ASSERT (0 <= m3 && m3 <= 9); + + int n1 = fstimeprec_file (tab, "/"); + int n2 = fstimeprec_file (tab, "."); + int n3 = fstimeprec_file (tab, ".."); + ASSERT (0 <= n1 && n1 <= 9); + ASSERT (0 <= n2 && n2 <= 9); + ASSERT (0 <= n3 && n3 <= 9); + + ASSERT (m1 <= n1); + ASSERT (m2 <= n2); + ASSERT (m3 <= n3); + + fstimeprec_free (tab); + + return 0; +} diff --git a/src/stat.c b/src/stat.c index d05a93b..cbf6d25 100644 --- a/src/stat.c +++ b/src/stat.c @@ -63,6 +63,7 @@ #include "file-type.h" #include "filemode.h" #include "fs.h" +#include "fstimeprec.h" #include "getopt.h" #include "mountlist.h" #include "quote.h" @@ -70,7 +71,6 @@ #include "stat-time.h" #include "strftime.h" #include "find-mount-point.h" -#include "xstrtol.h" #include "xvasprintf.h" #if USE_STATVFS @@ -183,6 +183,10 @@ static bool interpret_backslash_escapes; "" for --printf=FMT, "\n" for --format=FMT (-c). */ static char const *trailing_delim = ""; +/* The representation of the decimal point in the current locale. */ +static char const *decimal_point; +static size_t decimal_point_len; + /* Return the type of the specified file system. Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris). Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0). @@ -463,69 +467,23 @@ human_time (struct timespec t) return str; } -/* Return a string representation (in static storage) - of the number of seconds in T since the epoch. */ -static char * ATTRIBUTE_WARN_UNUSED_RESULT -epoch_sec (struct timespec t) -{ - static char str[INT_BUFSIZE_BOUND (time_t)]; - return timetostr (t.tv_sec, str); -} - -/* Output the number of nanoseconds, ARG.tv_nsec, honoring a - WIDTH.PRECISION format modifier, where PRECISION specifies - how many leading digits(on a field of 9) to print. */ -static void -out_ns (char *pformat, size_t prefix_len, struct timespec arg) -{ - /* If no format modifier is specified, i.e., nothing between the - "%" and ":" of "%:X", then use the default of zero-padding and - a width of 9. Otherwise, use the specified modifier(s). - This is to avoid the mistake of omitting the zero padding on - a number with fewer digits than the field width: when printing - nanoseconds after a decimal place, the resulting floating point - fraction would be off by a factor of 10 or more. - - If a precision/max width is specified, i.e., a '.' is present - in the modifier, then then treat the modifier as operating - on the default representation, i.e., a zero padded number - of width 9. */ - unsigned long int ns = arg.tv_nsec; - - if (memchr (pformat, '.', prefix_len)) /* precision specified. */ - { - char tmp[INT_BUFSIZE_BOUND (uintmax_t)]; - snprintf (tmp, sizeof tmp, "%09lu", ns); - strcpy (pformat + prefix_len, "s"); - printf (pformat, tmp); - } - else - { - char const *fmt = (prefix_len == 1) ? "09lu" : "lu"; - /* Note that pformat is big enough, as %:X -> %09lu - and two extra bytes are already allocated. */ - strcpy (pformat + prefix_len, fmt); - printf (pformat, ns); - } -} - static void out_string (char *pformat, size_t prefix_len, char const *arg) { strcpy (pformat + prefix_len, "s"); printf (pformat, arg); } -static void +static int out_int (char *pformat, size_t prefix_len, intmax_t arg) { strcpy (pformat + prefix_len, PRIdMAX); - printf (pformat, arg); + return printf (pformat, arg); } -static void +static int out_uint (char *pformat, size_t prefix_len, uintmax_t arg) { strcpy (pformat + prefix_len, PRIuMAX); - printf (pformat, arg); + return printf (pformat, arg); } static void out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg) @@ -539,6 +497,120 @@ out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) strcpy (pformat + prefix_len, PRIxMAX); printf (pformat, arg); } +static int +out_minus_zero (char *pformat, size_t prefix_len) +{ + strcpy (pformat + prefix_len, ".0f"); + return printf (pformat, -0.25); +} + +/* Output the number of seconds since the Epoch, using a format that + acts like printf's %f format. */ +static void +out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, + struct timespec arg) +{ + char *dot = memchr (pformat, '.', prefix_len); + size_t sec_prefix_len = prefix_len; + int width = 0; + int precision = 0; + bool frac_left_adjust = false; + + if (dot) + { + sec_prefix_len = dot - pformat; + pformat[prefix_len] = '\0'; + + if (ISDIGIT (dot[1])) + { + long int lprec = strtol (dot + 1, NULL, 10); + precision = (lprec <= INT_MAX ? lprec : INT_MAX); + } + else + { + static struct fstimeprec *tab; + if (! tab) + tab = fstimeprec_alloc (); + precision = fstimeprec (tab, statbuf); + } + + if (precision && ISDIGIT (dot[-1])) + { + /* If a nontrivial width is given, subtract the width of the + decimal point and PRECISION digits that will be output + later. */ + char *p = dot; + *dot = '\0'; + + do + --p; + while (ISDIGIT (p[-1])); + + long int lwidth = strtol (p, NULL, 10); + width = (lwidth <= INT_MAX ? lwidth : INT_MAX); + if (1 < width) + { + p += (*p == '0'); + sec_prefix_len = p - pformat; + int w_d = (decimal_point_len < width + ? width - decimal_point_len + : 0); + if (1 < w_d) + { + int w = w_d - precision; + if (1 < w) + { + char *dst = pformat; + for (char const *src = dst; src < p; src++) + if (*src == '-') + frac_left_adjust = true; + else + *dst++ = *src; + sec_prefix_len = + (dst - pformat + + (frac_left_adjust ? 0 : sprintf (dst, "%d", w))); + } + } + } + } + } + + int divisor = 1; + for (int i = precision; i < 9; i++) + divisor *= 10; + int frac_sec = arg.tv_nsec / divisor; + int int_len; + + if (TYPE_SIGNED (time_t)) + { + bool minus_zero = false; + if (arg.tv_sec < 0 && arg.tv_nsec != 0) + { + int frac_sec_modulus = 1000000000 / divisor; + frac_sec = (frac_sec_modulus - frac_sec + - (arg.tv_nsec % divisor != 0)); + arg.tv_sec += (frac_sec != 0); + minus_zero = (arg.tv_sec == 0); + } + int_len = (minus_zero + ? out_minus_zero (pformat, sec_prefix_len) + : out_int (pformat, sec_prefix_len, arg.tv_sec)); + } + else + int_len = out_uint (pformat, sec_prefix_len, arg.tv_sec); + + if (precision) + { + int prec = (precision < 9 ? precision : 9); + int trailing_prec = precision - prec; + int ilen = (int_len < 0 ? 0 : int_len); + int trailing_width = (ilen < width && decimal_point_len < width - ilen + ? width - ilen - decimal_point_len - prec + : 0); + printf ("%s%.*d%-*.*d", decimal_point, prec, frac_sec, + trailing_width, trailing_prec, 0); + } +} /* Print the context information of FILENAME, and return true iff the context could not be obtained. */ @@ -853,38 +925,26 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, } break; case 'W': - out_string (pformat, prefix_len, - epoch_sec (neg_to_zero (get_stat_birthtime (statbuf)))); - break; - case 'W' + 256: - out_ns (pformat, prefix_len, neg_to_zero (get_stat_birthtime (statbuf))); + out_epoch_sec (pformat, prefix_len, statbuf, + neg_to_zero (get_stat_birthtime (statbuf))); break; case 'x': out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); break; case 'X': - out_string (pformat, prefix_len, epoch_sec (get_stat_atime (statbuf))); - break; - case 'X' + 256: - out_ns (pformat, prefix_len, get_stat_atime (statbuf)); + out_epoch_sec (pformat, prefix_len, statbuf, 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_sec (get_stat_mtime (statbuf))); - break; - case 'Y' + 256: - out_ns (pformat, prefix_len, get_stat_mtime (statbuf)); + out_epoch_sec (pformat, prefix_len, statbuf, 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_sec (get_stat_ctime (statbuf))); - break; - case 'Z' + 256: - out_ns (pformat, prefix_len, get_stat_ctime (statbuf)); + out_epoch_sec (pformat, prefix_len, statbuf, get_stat_ctime (statbuf)); break; case 'C': fail |= out_file_context (pformat, prefix_len, filename); @@ -968,21 +1028,9 @@ 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; + unsigned int fmt_code = *fmt_char; memcpy (dest, b, len + 1); - /* The ":" modifier just before the letter in %W, %X, %Y, %Z - tells stat to print the nanoseconds portion of the date. */ - if (*fmt_char == ':' && strchr ("WXYZ", fmt_char[1])) - { - fmt_code = fmt_char[1] + 256; - ++fmt_char; - } - else - { - fmt_code = fmt_char[0]; - } - b = fmt_char; switch (fmt_code) { @@ -1276,16 +1324,12 @@ The valid format sequences for files (without --file-system):\n\ %U User name of owner\n\ %w Time of file birth, human-readable; - if unknown\n\ %W Time of file birth, seconds since Epoch; 0 if unknown\n\ - %:W Time of file birth, nanoseconds remainder; 0 if unknown\n\ %x Time of last access, human-readable\n\ %X Time of last access, seconds since Epoch\n\ - %:X Time of last access, nanoseconds remainder\n\ %y Time of last modification, human-readable\n\ %Y Time of last modification, seconds since Epoch\n\ - %:Y Time of last modification, nanoseconds remainder\n\ %z Time of last change, human-readable\n\ %Z Time of last change, seconds since Epoch\n\ - %:Z Time of last change, nanoseconds remainder\n\ \n\ "), stdout); @@ -1330,6 +1374,10 @@ main (int argc, char *argv[]) bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + struct lconv const *locale = localeconv (); + decimal_point = (locale->decimal_point[0] ? locale->decimal_point : "."); + decimal_point_len = strlen (decimal_point); + atexit (close_stdout); while ((c = getopt_long (argc, argv, "c:fLt", long_options, NULL)) != -1) diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds index 314f43e..9071ae9 100755 --- a/tests/misc/stat-nanoseconds +++ b/tests/misc/stat-nanoseconds @@ -19,18 +19,25 @@ test "$VERBOSE" = yes && stat --version . "${srcdir=.}/init.sh"; path_prepend_ ../src -touch -d '2010-10-21 18:43:33.023456789' k || framework_failure_ +TZ=UTC0 +export TZ + +touch -d '1970-01-01 18:43:33.023456789' k || framework_failure_ ls --full-time | grep 18:43:33.023456789 \ || skip_ this file system does not support sub-second time stamps -test "$(stat -c %:X k)" = 023456789 || fail=1 -test "$(stat -c %3:X k)" = 23456789 || fail=1 -test "$(stat -c %3.3:X k)" = 023 || fail=1 -test "$(stat -c %.3:X k)" = 023 || fail=1 -test "$(stat -c %03.3:X k)" = 023 || fail=1 -test "$(stat -c %-5.3:X k)" = '023 ' || fail=1 -test "$(stat -c %05.3:X k)" = ' 023' || fail=1 -test "$(stat -c %010.3:X k)" = ' 023' || fail=1 +test "$(stat -c %X k)" = 67413 || fail=1 +test "$(stat -c %.X k)" = 67413.023456789 || fail=1 +test "$(stat -c %.1X k)" = 67413.0 || fail=1 +test "$(stat -c %.3X k)" = 67413.023 || fail=1 +test "$(stat -c %.6X k)" = 67413.023456 || fail=1 +test "$(stat -c %.9X k)" = 67413.023456789 || fail=1 +test "$(stat -c %13.6X k)" = ' 67413.023456' || fail=1 +test "$(stat -c %013.6X k)" = 067413.023456 || fail=1 +test "$(stat -c %-13.6X k)" = '67413.023456 ' || fail=1 +test "$(stat -c %18.10X k)" = ' 67413.0234567890' || fail=1 +test "$(stat -c %018.10X k)" = 0067413.0234567890 || fail=1 +test "$(stat -c %-18.10X k)" = '67413.0234567890 ' || fail=1 Exit $fail diff --git a/tests/touch/60-seconds b/tests/touch/60-seconds index d008296..e06c770 100755 --- a/tests/touch/60-seconds +++ b/tests/touch/60-seconds @@ -30,7 +30,7 @@ echo 60.000000000 > exp || framework_failure # an `invalid date format'. Specifying 60 seconds *is* valid. TZ=UTC0 touch -t 197001010000.60 f || fail=1 -stat --p='%Y.%:Y\n' f > out || fail=1 +stat --p='%.9Y\n' f > out || fail=1 compare out exp || fail=1 -- 1.7.2
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 06 Nov 2010 08:16:02 GMT) Full text and rfc822 format available.Message #53 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 06 Nov 2010 09:20:06 +0100
Paul Eggert wrote: > On 11/04/2010 11:34 PM, Jim Meyering wrote: >> Pádraig Brady wrote: >>> I still slightly prefer just using %.X as >>> it's backwards compat with older coreutils (excluding 8.6). >> >> So do I. > > I built that and tried it out, and found another problem that has been > annoying me for years in other programs: 'stat' prints out unnecessary > trailing zeros for time stamps, when the file system resolution is > coarser than nanosecond resolution. So I figured I'd fix that too, > for 'stat' (other programs can be fixed later). With this fix, %.X > outputs the time stamp but omits trailing zeros if it can infer that > the file system would always put zeros there. If you want a specific > number of zeros, you can use something like %.3X or %.9X (or %.100X :-). Nice! > Subject: [PATCH] stat: use e.g. %.3X instead of %X.%3:X for sub-second precision > > * NEWS: Document this. > * doc/coreutils.texi (stat invocation): Likewise. > * gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec: > * gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c: > New files. > * bootstrap.conf (gnulib_modules): Add fstimeprec. > * src/stat.c: Include fstimeprec.h. Don't include xstrtol.h. > (decimal_point, decimal_point_len): New static vars. > (main): Initialize them. > (epoch_sec, out_ns): Remove. > (out_int, out_uint): Now returns whatever printf returned. > (out_minus_zero, out_epoch_secs): New functions. > (print_stat): Use out_epoch_sec instead of out_ns and epoch_sec. > (print_stat, print_it, usage): Remove the %:X-style formats. > * tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems > with weird time zones. Use a time stamp near the Epoch so that we > don't have to worry about leap seconds. Redo test cases to match Both of those ideas seem useful enough to employ in general, so I copied your log comments into the code. > new behavior. > * tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to > new behavior. I haven't looked through all of it yet, but here's a small change I'll fold in: diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds index 9071ae9..0f41eb0 100755 --- a/tests/misc/stat-nanoseconds +++ b/tests/misc/stat-nanoseconds @@ -19,9 +19,11 @@ test "$VERBOSE" = yes && stat --version . "${srcdir=.}/init.sh"; path_prepend_ ../src +# Set this to avoid problems with weird time zones. TZ=UTC0 export TZ +# Use a time stamp near the Epoch to avoid trouble with leap seconds. touch -d '1970-01-01 18:43:33.023456789' k || framework_failure_ ls --full-time | grep 18:43:33.023456789 \ FYI, after I push this, I'll update to the latest from gnulib for strtod and icc-related fixes and make another snapshot.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 06 Nov 2010 09:17:02 GMT) Full text and rfc822 format available.Message #56 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 06 Nov 2010 10:21:03 +0100
Paul Eggert wrote: ... > Subject: [PATCH] stat: use e.g. %.3X instead of %X.%3:X for sub-second precision Thanks again. Here's one more small change I'm including, to put braces around this four-line "for"-loop body: [per HACKING's "Curly braces" guidelines] diff --git a/src/stat.c b/src/stat.c index cbf6d25..99f115b 100644 --- a/src/stat.c +++ b/src/stat.c @@ -562,10 +562,12 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, { char *dst = pformat; for (char const *src = dst; src < p; src++) - if (*src == '-') - frac_left_adjust = true; - else - *dst++ = *src; + { + if (*src == '-') + frac_left_adjust = true; + else + *dst++ = *src; + } sec_prefix_len = (dst - pformat + (frac_left_adjust ? 0 : sprintf (dst, "%d", w)));
Pádraig Brady <P <at> draigBrady.com>
:Jim Meyering <jim <at> meyering.net>
:Message #61 received at 7325-done <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325-done <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 06 Nov 2010 14:20:50 +0000
On 06/11/10 02:54, Paul Eggert wrote: > On 11/04/2010 11:34 PM, Jim Meyering wrote: >> Pádraig Brady wrote: >>> I still slightly prefer just using %.X as >>> it's backwards compat with older coreutils (excluding 8.6). >> >> So do I. > > I built that and tried it out, and found another problem that has been > annoying me for years in other programs: 'stat' prints out unnecessary > trailing zeros for time stamps, when the file system resolution is > coarser than nanosecond resolution. So I figured I'd fix that too, > for 'stat' (other programs can be fixed later). With this fix, %.X > outputs the time stamp but omits trailing zeros if it can infer that > the file system would always put zeros there. If you want a specific > number of zeros, you can use something like %.3X or %.9X (or %.100X :-). Interesting. So it's variable precision by default $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 0.000000000 63813.500000000 63813.500000000 1289052572.699980883 $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 0.00000000 63813.50000000 63813.50000000 1289052573.53698077 I like it. BTW you dropped a blank line at the end of the NEWS section. cheers, Pádraig. p.s. I'm marking this bug as done
Message #62 received at 7325-done <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: 7325-done <at> debbugs.gnu.org, Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 06 Nov 2010 15:37:44 +0100
Pádraig Brady wrote: > On 06/11/10 02:54, Paul Eggert wrote: >> On 11/04/2010 11:34 PM, Jim Meyering wrote: >>> Pádraig Brady wrote: >>>> I still slightly prefer just using %.X as >>>> it's backwards compat with older coreutils (excluding 8.6). >>> >>> So do I. >> >> I built that and tried it out, and found another problem that has been >> annoying me for years in other programs: 'stat' prints out unnecessary >> trailing zeros for time stamps, when the file system resolution is >> coarser than nanosecond resolution. So I figured I'd fix that too, >> for 'stat' (other programs can be fixed later). With this fix, %.X >> outputs the time stamp but omits trailing zeros if it can infer that >> the file system would always put zeros there. If you want a specific >> number of zeros, you can use something like %.3X or %.9X (or %.100X :-). > > Interesting. So it's variable precision by default > > $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 > 0.000000000 63813.500000000 63813.500000000 1289052572.699980883 > $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 > 0.00000000 63813.50000000 63813.50000000 1289052573.53698077 > > I like it. > > BTW you dropped a blank line at the end of the NEWS section. Good catch. I've adjusted his patch. That happens regularly, so we should add a check for this. Here's a start: sed -n 4,/Noteworthy/p NEWS| perl -n0e '/\n\n\n\* Noteworthy.*$/ or die' > p.s. I'm marking this bug as done Thanks. BTW, I've just pushed Paul's patch and the fix for FreeBSD's /bin/sh bug, and made a snapshot.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Mon, 08 Nov 2010 12:56:02 GMT) Full text and rfc822 format available.Message #65 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: 7325 <at> debbugs.gnu.org, Paul Eggert <eggert <at> CS.UCLA.EDU>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 12:59:51 +0000
On 06/11/10 14:20, Pádraig Brady wrote: > On 06/11/10 02:54, Paul Eggert wrote: >> On 11/04/2010 11:34 PM, Jim Meyering wrote: >>> Pádraig Brady wrote: >>>> I still slightly prefer just using %.X as >>>> it's backwards compat with older coreutils (excluding 8.6). >>> >>> So do I. >> >> I built that and tried it out, and found another problem that has been >> annoying me for years in other programs: 'stat' prints out unnecessary >> trailing zeros for time stamps, when the file system resolution is >> coarser than nanosecond resolution. So I figured I'd fix that too, >> for 'stat' (other programs can be fixed later). With this fix, %.X >> outputs the time stamp but omits trailing zeros if it can infer that >> the file system would always put zeros there. If you want a specific >> number of zeros, you can use something like %.3X or %.9X (or %.100X :-). > > Interesting. So it's variable precision by default > > $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 > 0.000000000 63813.500000000 63813.500000000 1289052572.699980883 > $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 > 0.00000000 63813.50000000 63813.50000000 1289052573.53698077 > > I like it. One caveat we should at least document is we can't rely on string comparison of timestamps. I.E. shell code like this could fail, because a change in atime for example, could cause a change in the returned mtime. # Wait for file to be modified "$ts" = $(stat -c "%.Y" file) while [ "$ts" = $(stat -c "%.Y" file) ]; do sleep .1; done cheers, Pádraig. From 42d77a300234f608b71c46f6a39bb3a1f4cb31d3 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?P=C3=A1draig=20Brady?= <P <at> draigBrady.com> Date: Mon, 8 Nov 2010 12:49:30 +0000 Subject: [PATCH] doc: mention a caveat with the new sub-second precision stat format * doc/coreutils.texi (stat invocation): Dissuade the use of the auto precision format with subsequent string comparisons. --- doc/coreutils.texi | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 8dfb069..e310c33 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10721,7 +10721,9 @@ print after the decimal point. For example, @samp{%.9X} outputs the last access time to nanosecond precision. If a period is given but no precision, @command{stat} uses the estimated precision of the file system. When discarding excess precision, time stamps are truncated -toward minus infinity. +toward minus infinity. Since this estimated precision can return +differing numbers of trailing zeros, the result should not be used +with string comparison operators in shell scripts for example. @example zero pad: -- 1.6.2.5
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Mon, 08 Nov 2010 14:29:02 GMT) Full text and rfc822 format available.Message #68 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> CS.UCLA.EDU>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 15:33:02 +0100
Pádraig Brady wrote: > On 06/11/10 14:20, Pádraig Brady wrote: >> On 06/11/10 02:54, Paul Eggert wrote: >>> On 11/04/2010 11:34 PM, Jim Meyering wrote: >>>> Pádraig Brady wrote: >>>>> I still slightly prefer just using %.X as >>>>> it's backwards compat with older coreutils (excluding 8.6). >>>> >>>> So do I. >>> >>> I built that and tried it out, and found another problem that has been >>> annoying me for years in other programs: 'stat' prints out unnecessary >>> trailing zeros for time stamps, when the file system resolution is >>> coarser than nanosecond resolution. So I figured I'd fix that too, >>> for 'stat' (other programs can be fixed later). With this fix, %.X >>> outputs the time stamp but omits trailing zeros if it can infer that >>> the file system would always put zeros there. If you want a specific >>> number of zeros, you can use something like %.3X or %.9X (or %.100X :-). >> >> Interesting. So it's variable precision by default >> >> $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 >> 0.000000000 63813.500000000 63813.500000000 1289052572.699980883 >> $ touch -d '1970-01-01 18:43:33.5000000000' 2; ~/git/t/coreutils/src/stat -c "%.W %.X %.Y %.Z" 2 >> 0.00000000 63813.50000000 63813.50000000 1289052573.53698077 >> >> I like it. > > One caveat we should at least document is > we can't rely on string comparison of timestamps. > I.E. shell code like this could fail, because > a change in atime for example, could cause > a change in the returned mtime. > > # Wait for file to be modified > "$ts" = $(stat -c "%.Y" file) > while [ "$ts" = $(stat -c "%.Y" file) ]; do sleep .1; done That's a compelling argument. It'd be very easy to write a script like that after seeing this sentence in NEWS: To obtain a full resolution time stamp for %X, use %.X; Viewed like that, it feels like we're providing a little too much rope here, and already nicely knotted and ready for use. I don't like seeing fewer digits of mtime precision just because atime nanoseconds happens to be a multiple of 10. Of course that happens in only ~1-in-10 times, and then only when the other nanosecond parts are in the same boat (see contrived example below). Then there are the even less frequent cases of 7 digits. Looks like I got very lucky here and hit a number of nanoseconds that happened to be a multiple of 100,000: $ for i in $(seq 1000); do touch -d '1970-01-01 18:43:33.5000000000' 2; t=$(stat -c "%.W %.X %.Y %.Z" 2); test $(echo "$t"|wc -c) -lt 57 && echo "$t"; done 0.000000 63813.500000 63813.500000 1289224045.731146 0.0000 63813.5000 63813.5000 1289224047.8224 [Exit 1] I realize this is due to the way the precision estimation heuristic works. Wondering if there's a less-surprising way to do that. Now, I'm thinking that this variable precision feature would be better if it were somehow optional, rather than the default for %.X. Consistency/reproducibility are more important, here.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Mon, 08 Nov 2010 15:19:02 GMT) Full text and rfc822 format available.Message #71 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Jim Meyering <jim <at> meyering.net> Cc: Paul Eggert <eggert <at> CS.UCLA.EDU>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 15:22:07 +0000
On 08/11/10 14:33, Jim Meyering wrote: > Looks like I got very lucky here and hit a number of nanoseconds > that happened to be a multiple of 100,000: > > $ for i in $(seq 1000); do touch -d '1970-01-01 18:43:33.5000000000' 2; t=$(stat -c "%.W %.X %.Y %.Z" 2); test $(echo "$t"|wc -c) -lt 57 && echo "$t"; done > 0.000000 63813.500000 63813.500000 1289224045.731146 > 0.0000 63813.5000 63813.5000 1289224047.8224 > [Exit 1] > > I realize this is due to the way the precision estimation > heuristic works. Wondering if there's a less-surprising > way to do that. You could snap to milli, micro, nano, though that would just mean it would happen less often. > Now, I'm thinking that this variable precision feature would be better > if it were somehow optional, rather than the default for %.X. > Consistency/reproducibility are more important, here. You could touch -d '0.123456789' stat.prec.test at program start, but that wouldn't always work. Non writable dir, disparity between read and write support for time stamp resolutions, :( You could sample X preexisting files/dirs on the same file system, and stop when Y have not increased in precision. That combined with snapping to milli,micro,nano would usually work. Though that's starting to get too hacky IMHO while still not being general. I guess we're back to doing 9 by default for %.Y and using %#.Y to mean auto precision ? cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Mon, 08 Nov 2010 15:27:02 GMT) Full text and rfc822 format available.Message #74 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> CS.UCLA.EDU>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 16:31:21 +0100
Pádraig Brady wrote: > On 08/11/10 14:33, Jim Meyering wrote: >> Looks like I got very lucky here and hit a number of nanoseconds >> that happened to be a multiple of 100,000: >> >> $ for i in $(seq 1000); do touch -d '1970-01-01 18:43:33.5000000000' 2; t=$(stat -c "%.W %.X %.Y %.Z" 2); test $(echo "$t"|wc -c) -lt 57 && echo "$t"; done >> 0.000000 63813.500000 63813.500000 1289224045.731146 >> 0.0000 63813.5000 63813.5000 1289224047.8224 >> [Exit 1] >> >> I realize this is due to the way the precision estimation >> heuristic works. Wondering if there's a less-surprising >> way to do that. > > You could snap to milli, micro, nano, > though that would just mean it would > happen less often. > >> Now, I'm thinking that this variable precision feature would be better >> if it were somehow optional, rather than the default for %.X. >> Consistency/reproducibility are more important, here. > > You could touch -d '0.123456789' stat.prec.test > at program start, but that wouldn't always work. > Non writable dir, disparity between read and > write support for time stamp resolutions, :( > > You could sample X preexisting files/dirs on the > same file system, and stop when Y have not increased > in precision. That combined with snapping to milli,micro,nano > would usually work. Though that's starting to > get too hacky IMHO while still not being general. I agree. The only possibility I can imagine is to use some sort of statfs-like interface that would provide file system time stamp resolution. > I guess we're back to doing 9 by default for %.Y > and using %#.Y to mean auto precision ? The default of 9 seems far less likely to cause subtle misuse. Letting the "#" in %#.Y mean auto precision sounds appropriate.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Mon, 08 Nov 2010 15:58:01 GMT) Full text and rfc822 format available.Message #77 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Eric Blake <eblake <at> redhat.com> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> CS.UCLA.EDU>, 7325 <at> debbugs.gnu.org, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 09:02:03 -0700
[Message part 1 (text/plain, inline)]
On 11/08/2010 08:22 AM, Pádraig Brady wrote: > On 08/11/10 14:33, Jim Meyering wrote: >> Looks like I got very lucky here and hit a number of nanoseconds >> that happened to be a multiple of 100,000: >> >> $ for i in $(seq 1000); do touch -d '1970-01-01 18:43:33.5000000000' 2; t=$(stat -c "%.W %.X %.Y %.Z" 2); test $(echo "$t"|wc -c) -lt 57 && echo "$t"; done >> 0.000000 63813.500000 63813.500000 1289224045.731146 >> 0.0000 63813.5000 63813.5000 1289224047.8224 >> [Exit 1] >> >> I realize this is due to the way the precision estimation >> heuristic works. Wondering if there's a less-surprising >> way to do that. > > You could snap to milli, micro, nano, > though that would just mean it would > happen less often. On cygwin, the default precision is 100nano (that is, 7 digits). See also gnulib/lib/utimecmp.c, which also sets up a hash table that tries to determine a file system's default resolution. In particular, it makes 100% correct analysis on file systems that support _PC_TIMESTAMP_RESOLUTION, but that's still pretty rare today. In fact, since Paul originally wrote utimecmp.c, I'm surprised that you rewrote the coreutils hash table from scratch rather than trying to reuse the code. -- Eric Blake eblake <at> redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
[signature.asc (application/pgp-signature, attachment)]
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Tue, 09 Nov 2010 00:55:02 GMT) Full text and rfc822 format available.Message #80 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Eric Blake <eblake <at> redhat.com> Cc: 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Mon, 08 Nov 2010 16:59:15 -0800
On 11/08/10 08:02, Eric Blake wrote: > In fact, since Paul originally wrote utimecmp.c, I'm surprised that you > rewrote the coreutils hash table from scratch rather than trying to > reuse the code. I had vaguely remembered the issue, but I had forgotten where I put that code. utimecmp.c modifies the time stamp of the files, right? So it might not be a good idea here. But perhaps some of the common code could be factored out. Getting back to the point: I don't see a problem with 'stat' backward compatibility. The guessed-resolution time stamps are output only if someone uses "%.X", which is a format that nobody would use before the change. So old scripts shouldn't be broken by the change. So it sounds like the issue is mostly about new scripts. But for those, we can tell people not to use "%.X" if they want to do textual comparison. Advice along these lines will be needed no matter what, because, even if we could determine timestamp resolution perfectly, there would still be a problem with blind use of "%.X". Suppose someone did something like this: ts=$(stat -c %.Y $old) cp -p $old $new # Wait for $new to be modified while [ $ts = $(stat -c %.Y $new) ]; do sleep .1; done This won't work as desired even if stat could deduce timestamp resolution perfectly, because $old and $new could be on different file systems, and $new's file system could have a coarser resolution than $old's. I can write a documentation patch along these lines if you like.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Tue, 09 Nov 2010 06:50:02 GMT) Full text and rfc822 format available.Message #83 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Pádraig Brady <P <at> draigBrady.com>, 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Tue, 09 Nov 2010 07:54:30 +0100
Paul Eggert wrote: > On 11/08/10 08:02, Eric Blake wrote: >> In fact, since Paul originally wrote utimecmp.c, I'm surprised that you >> rewrote the coreutils hash table from scratch rather than trying to >> reuse the code. > > I had vaguely remembered the issue, but I had forgotten where I put > that code. utimecmp.c modifies the time stamp of the files, right? > So it might not be a good idea here. But perhaps some of the common > code could be factored out. > > Getting back to the point: I don't see a problem with 'stat' backward compatibility. > The guessed-resolution time stamps are output only if someone uses "%.X", > which is a format that nobody would use before the change. So old > scripts shouldn't be broken by the change. > > So it sounds like the issue is mostly about new scripts. But for Yes. > those, we can tell people not to use "%.X" if they want to do textual The semantics of this feature feel rather involved for something that looks like a simple default. Some will not read the caveat. > comparison. Advice along these lines will be needed no matter what, > because, even if we could determine timestamp resolution perfectly, > there would still be a problem with blind use of "%.X". Suppose someone > did something like this: > > ts=$(stat -c %.Y $old) > cp -p $old $new > # Wait for $new to be modified > while [ $ts = $(stat -c %.Y $new) ]; do sleep .1; done > > This won't work as desired even if stat could deduce timestamp resolution > perfectly, because $old and $new could be on different file systems, > and $new's file system could have a coarser resolution than $old's. > > I can write a documentation patch along these lines if you like. Isn't this a good reason to attach the variable-width functionality to a less-likely-to-be-(ab)used syntax like "%#.X"? Then we would put that format directive in the default format string, where its output is parsed only by humans, and scripts using the shorter %.X would be less error prone.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Wed, 10 Nov 2010 09:01:02 GMT) Full text and rfc822 format available.Message #86 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: P, ádraig Brady <P <at> draigBrady.com>, 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 10 Nov 2010 10:04:52 +0100
Jim Meyering wrote: > Paul Eggert wrote: > >> On 11/08/10 08:02, Eric Blake wrote: >>> In fact, since Paul originally wrote utimecmp.c, I'm surprised that you >>> rewrote the coreutils hash table from scratch rather than trying to >>> reuse the code. >> >> I had vaguely remembered the issue, but I had forgotten where I put >> that code. utimecmp.c modifies the time stamp of the files, right? >> So it might not be a good idea here. But perhaps some of the common >> code could be factored out. >> >> Getting back to the point: I don't see a problem with 'stat' >> backward compatibility. >> The guessed-resolution time stamps are output only if someone uses "%.X", >> which is a format that nobody would use before the change. So old >> scripts shouldn't be broken by the change. >> >> So it sounds like the issue is mostly about new scripts. But for > > Yes. > >> those, we can tell people not to use "%.X" if they want to do textual > > The semantics of this feature feel rather involved for something that > looks like a simple default. Some will not read the caveat. > >> comparison. Advice along these lines will be needed no matter what, >> because, even if we could determine timestamp resolution perfectly, >> there would still be a problem with blind use of "%.X". Suppose someone >> did something like this: >> >> ts=$(stat -c %.Y $old) >> cp -p $old $new >> # Wait for $new to be modified >> while [ $ts = $(stat -c %.Y $new) ]; do sleep .1; done >> >> This won't work as desired even if stat could deduce timestamp resolution >> perfectly, because $old and $new could be on different file systems, >> and $new's file system could have a coarser resolution than $old's. >> >> I can write a documentation patch along these lines if you like. > > Isn't this a good reason to attach the variable-width functionality > to a less-likely-to-be-(ab)used syntax like "%#.X"? Then we would put > that format directive in the default format string, where its output > is parsed only by humans, and scripts using the shorter %.X > would be less error prone. Unless I hear otherwise soon, I'll use something like the following basis for the proposed change: (of course, this needs additional tests and probably documentation changes) diff --git a/src/stat.c b/src/stat.c index ae7ce02..98b7501 100644 --- a/src/stat.c +++ b/src/stat.c @@ -550,18 +550,27 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, sec_prefix_len = dot - pformat; pformat[prefix_len] = '\0'; + /* %.X => precision defaults to 9 + %.5X => precision is 5 + %#.X => precision is determined by fstimeprec + %#.3X => precision is 3 (specified overrides "#") */ + if (ISDIGIT (dot[1])) { long int lprec = strtol (dot + 1, NULL, 10); precision = (lprec <= INT_MAX ? lprec : INT_MAX); } - else + else if (memchr (pformat, '#', dot - pformat)) { static struct fstimeprec *tab; if (! tab) tab = fstimeprec_alloc (); precision = fstimeprec (tab, statbuf); } + else + { + precision = 9; + } if (precision && ISDIGIT (dot[-1])) {
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 07:08:01 GMT) Full text and rfc822 format available.Message #89 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: Pád, raig Brady <P <at> draigBrady.com>, 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Wed, 10 Nov 2010 23:11:58 -0800
On 11/10/2010 01:04 AM, Jim Meyering wrote: > + /* %.X => precision defaults to 9 > + %.5X => precision is 5 > + %#.X => precision is determined by fstimeprec > + %#.3X => precision is 3 (specified overrides "#") */ How about something like this instead? %.X => precision is 9 (until POSIX goes sub-nanosecond :-) %.5X => precision is 5 %.*X => precision determined by fstimeprec Then there's no reason for the "overrides" case.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 11:45:02 GMT) Full text and rfc822 format available.Message #92 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: P, ádraig Brady <P <at> draigBrady.com>, 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 12:49:10 +0100
Paul Eggert wrote: > On 11/10/2010 01:04 AM, Jim Meyering wrote: >> + /* %.X => precision defaults to 9 >> + %.5X => precision is 5 >> + %#.X => precision is determined by fstimeprec >> + %#.3X => precision is 3 (specified overrides "#") */ > > How about something like this instead? > > %.X => precision is 9 (until POSIX goes sub-nanosecond :-) > %.5X => precision is 5 > %.*X => precision determined by fstimeprec > > Then there's no reason for the "overrides" case. Good idea. I prefer that. From 26e466e056462448e81536d9a96499fbe1f725ef Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Wed, 10 Nov 2010 12:28:30 +0100 Subject: [PATCH] stat: default to precision=9; now %.*X uses variable --- src/stat.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/stat.c b/src/stat.c index ae7ce02..7ceb9c1 100644 --- a/src/stat.c +++ b/src/stat.c @@ -550,18 +550,26 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, sec_prefix_len = dot - pformat; pformat[prefix_len] = '\0'; + /* %.X => precision defaults to 9 + %.5X => precision is 5 + %.*X => precision is determined by fstimeprec */ + if (ISDIGIT (dot[1])) { long int lprec = strtol (dot + 1, NULL, 10); precision = (lprec <= INT_MAX ? lprec : INT_MAX); } - else + else if (dot[1] == '*') { static struct fstimeprec *tab; if (! tab) tab = fstimeprec_alloc (); precision = fstimeprec (tab, statbuf); } + else + { + precision = 9; + } if (precision && ISDIGIT (dot[-1])) { @@ -1061,7 +1069,8 @@ print_it (char const *format, char const *filename, char const *fmt_char = b + len + 1; fmt_char += strspn (fmt_char, digits); if (*fmt_char == '.') - fmt_char += 1 + strspn (fmt_char + 1, digits); + fmt_char += 1 + (fmt_char[1] == '*' + ? 1 : strspn (fmt_char + 1, digits)); len = fmt_char - (b + 1); unsigned int fmt_code = *fmt_char; memcpy (dest, b, len + 1); -- 1.7.3.2.4.g60aa9
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 12:01:02 GMT) Full text and rfc822 format available.Message #95 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Jim Meyering <jim <at> meyering.net> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 12:04:47 +0000
On 11/11/10 11:49, Jim Meyering wrote: > Paul Eggert wrote: > >> On 11/10/2010 01:04 AM, Jim Meyering wrote: >>> + /* %.X => precision defaults to 9 >>> + %.5X => precision is 5 >>> + %#.X => precision is determined by fstimeprec >>> + %#.3X => precision is 3 (specified overrides "#") */ >> >> How about something like this instead? >> >> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >> %.5X => precision is 5 >> %.*X => precision determined by fstimeprec >> >> Then there's no reason for the "overrides" case. > > Good idea. I prefer that. Well the reason I chose %#.X was that it was the standard mechanism for choosing "alternate form" and so was backwards compat with previous stats. I.E. on any stat "%#.X" would give the best available precision. cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 13:22:01 GMT) Full text and rfc822 format available.Message #98 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 14:25:55 +0100
Pádraig Brady wrote: > On 11/11/10 11:49, Jim Meyering wrote: >> Paul Eggert wrote: >> >>> On 11/10/2010 01:04 AM, Jim Meyering wrote: >>>> + /* %.X => precision defaults to 9 >>>> + %.5X => precision is 5 >>>> + %#.X => precision is determined by fstimeprec >>>> + %#.3X => precision is 3 (specified overrides "#") */ >>> >>> How about something like this instead? >>> >>> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >>> %.5X => precision is 5 >>> %.*X => precision determined by fstimeprec >>> >>> Then there's no reason for the "overrides" case. >> >> Good idea. I prefer that. > > Well the reason I chose %#.X was that it was the > standard mechanism for choosing "alternate form" > and so was backwards compat with previous stats. > I.E. on any stat "%#.X" would give the best > available precision. I prefer the "%.*X" notation because things to the right of the "." denote precision. It's slightly odd in that it looks like the invoker might provide the actual number somehow, but once you know the rule that precision comes from fstimeprec, it makes sense. for i in $(seq 10); do touch -d '1970-01-01 18:43:33.5000000000' k src/stat -c "%.*Y" k done ... 63813.50000000 63813.500000000 63813.5000000 63813.500000000
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 13:50:03 GMT) Full text and rfc822 format available.Message #101 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 14:54:40 +0100
Pádraig Brady wrote: > On 11/11/10 11:49, Jim Meyering wrote: >> Paul Eggert wrote: >> >>> On 11/10/2010 01:04 AM, Jim Meyering wrote: >>>> + /* %.X => precision defaults to 9 >>>> + %.5X => precision is 5 >>>> + %#.X => precision is determined by fstimeprec >>>> + %#.3X => precision is 3 (specified overrides "#") */ >>> >>> How about something like this instead? >>> >>> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >>> %.5X => precision is 5 >>> %.*X => precision determined by fstimeprec >>> >>> Then there's no reason for the "overrides" case. >> >> Good idea. I prefer that. ... Regardless, of syntax, can any of you suggest a good way to test this? I can think of a few, but each has disadvantages. - mount an ext2 file system and ensure that there are no nanoseconds Pro: works all the time, as long as ext2 is an option Con: root-only and requires mkfs.ext2 Code: dd if=/dev/zero of=blob count=2 seek=2M > /dev/null || skip=1 mkdir mnt || skip=1 mkfs -t ext2 -F blob \ || skip_test_ "failed to create ext2 file system" mount -oloop blob mnt || skip=1 touch -d '1970-01-01 18:43:33.5000000000' k || fail=1 test "$(stat -c '%.*Y' k)" = 63813 || fail=1 - require a modern file system type and run a loop like this, hoping to find a time stamp with fewer than "normal" digits of nanosecond precision. $ for i in $(seq 10); do rm -f k; touch -d '1970-01-01 18:43:33.5000000000' k; /cu/src/stat -c "%.*Y" k; done 63813.500000000 63813.50000000 63813.500000000 63813.500000000 63813.500000000 63813.50000000 63813.500000000 63813.500000000 63813.500000000 63813.500000000 Pro: does not require mount privileges Con: I suppose it may fail some of the time, no matter how many iterations we perform.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 14:23:02 GMT) Full text and rfc822 format available.Message #104 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Jim Meyering <jim <at> meyering.net> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 14:26:55 +0000
On 11/11/10 12:04, Pádraig Brady wrote: > On 11/11/10 11:49, Jim Meyering wrote: >> Paul Eggert wrote: >> >>> On 11/10/2010 01:04 AM, Jim Meyering wrote: >>>> + /* %.X => precision defaults to 9 >>>> + %.5X => precision is 5 >>>> + %#.X => precision is determined by fstimeprec >>>> + %#.3X => precision is 3 (specified overrides "#") */ >>> >>> How about something like this instead? >>> >>> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >>> %.5X => precision is 5 >>> %.*X => precision determined by fstimeprec >>> >>> Then there's no reason for the "overrides" case. >> >> Good idea. I prefer that. > > Well the reason I chose %#.X was that it was the > standard mechanism for choosing "alternate form" > and so was backwards compat with previous stats. > I.E. on any stat "%#.X" would give the best > available precision. An alternative perhaps that doesn't require the above override behavior and is also forwards compat, is to use %.0X rather than %.*X I.E. 0 selects the auto precision, and if you really don't want any decimal places then don't use "." at all? I don't feel strongly about any of these. I slightly prefer being forwardss compat though. I.E. that old versions of stat work with newer scripts. cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 14:51:02 GMT) Full text and rfc822 format available.Message #107 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Jim Meyering <jim <at> meyering.net> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 14:54:47 +0000
On 11/11/10 13:54, Jim Meyering wrote: > Pádraig Brady wrote: > >> On 11/11/10 11:49, Jim Meyering wrote: >>> Paul Eggert wrote: >>> >>>> On 11/10/2010 01:04 AM, Jim Meyering wrote: >>>>> + /* %.X => precision defaults to 9 >>>>> + %.5X => precision is 5 >>>>> + %#.X => precision is determined by fstimeprec >>>>> + %#.3X => precision is 3 (specified overrides "#") */ >>>> >>>> How about something like this instead? >>>> >>>> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >>>> %.5X => precision is 5 >>>> %.*X => precision determined by fstimeprec >>>> >>>> Then there's no reason for the "overrides" case. >>> >>> Good idea. I prefer that. > ... > > Regardless, of syntax, can any of you suggest a good way to test this? > I can think of a few, but each has disadvantages. > > - mount an ext2 file system and ensure that there are no nanoseconds > Pro: works all the time, as long as ext2 is an option > Con: root-only and requires mkfs.ext2 > > Code: > dd if=/dev/zero of=blob count=2 seek=2M > /dev/null || skip=1 > mkdir mnt || skip=1 > mkfs -t ext2 -F blob \ > || skip_test_ "failed to create ext2 file system" > mount -oloop blob mnt || skip=1 > touch -d '1970-01-01 18:43:33.5000000000' k || fail=1 > test "$(stat -c '%.*Y' k)" = 63813 || fail=1 > > - require a modern file system type and run a loop like this, > hoping to find a time stamp with fewer than "normal" digits of > nanosecond precision. > > $ for i in $(seq 10); do rm -f k; touch -d '1970-01-01 18:43:33.5000000000' k; /cu/src/stat -c "%.*Y" k; done > 63813.500000000 > 63813.50000000 > 63813.500000000 > 63813.500000000 > 63813.500000000 > 63813.50000000 > 63813.500000000 > 63813.500000000 > 63813.500000000 > 63813.500000000 > > Pro: does not require mount privileges > Con: I suppose it may fail some of the time, no matter how many > iterations we perform. > I prefer the latter. It's quick to run so do it 100 times require_nanosecond_fs_ # Set this to avoid problems with weird time zones. TZ=UTC0 export TZ # Use a time stamp near the Epoch to avoid trouble with leap seconds. touch -d '1970-01-01 18:43:33.5' k || framework_failure_ prec=$(for i in $(seq 100); do touch -a k; stat -c "%.*Y" k done | cut -d. -f2 | wc -L) test "$prec" = 9 || fail=1
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 15:21:01 GMT) Full text and rfc822 format available.Message #110 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Eric Blake <eblake <at> redhat.com> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, 7325 <at> debbugs.gnu.org, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 08:24:52 -0700
[Message part 1 (text/plain, inline)]
On 11/11/2010 07:26 AM, Pádraig Brady wrote: >>>> %.*X => precision determined by fstimeprec >>>> > > An alternative perhaps that doesn't require the above override > behavior and is also forwards compat, is to use %.0X rather than %.*X That sounds nicer to me. I look at %.*X and think I have to supply the precision, but %.0X as a mnemonic of 'show full precision but suppress trailing zeros' kind of makes sense, and looks nicer than %#.X. -- Eric Blake eblake <at> redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
[signature.asc (application/pgp-signature, attachment)]
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 17:50:03 GMT) Full text and rfc822 format available.Message #113 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Eric Blake <eblake <at> redhat.com> Cc: 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 09:54:14 -0800
On 11/11/2010 07:24 AM, Eric Blake wrote: > %.0X as a mnemonic of 'show full precision but suppress > trailing zeros' kind of makes sense I had considered supporting those semantics as well, which would have avoided all this business with fstimeprec. That is, just trim trailing zeros, and don't worry about the file system time stamp resolution. The problem with this approach is that different time stamps for the same file (atime, mtime, ctime) might show different numbers of digits, which might cause alignment problems and confusion. I'm a bit leery of %.0X as meaning "show more than zero digits of precision", since .0 always means show zero everywhere else that printf-style formats are used. I'm still not quite following the backward compatibility argument, as no matter what we do, we'll have different functionality than before. %#.X outputs an integer time stamp with coreutils 5.97 and outputs nothing with coreutils 8.6. %.0X is the same as %#.X, so they're both equally "bad" in that respect. %.*X outputs "*X" with 5.97 and "?X" with 8.6, so it's not portable either. It's not a big deal, but I still mildly prefer the * notation. By the way, while we're on the subject (:-), 'stat' uses wildly different strategies when dealing with invalid formats. Sometimes it outputs a diagnostic, sometimes it silently outputs a question mark, sometimes it silently outputs the format itself. At some point somebody should rationalize this. I suggest having 'stat' output the format itself, as that makes diagnosis easy and intuitive.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Thu, 11 Nov 2010 22:05:01 GMT) Full text and rfc822 format available.Message #116 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: 7325 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>, Jim Meyering <jim <at> meyering.net> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Thu, 11 Nov 2010 22:09:17 +0000
On 11/11/10 17:54, Paul Eggert wrote: > On 11/11/2010 07:24 AM, Eric Blake wrote: >> %.0X as a mnemonic of 'show full precision but suppress >> trailing zeros' kind of makes sense > > I had considered supporting those semantics > as well, which would have avoided all this business with > fstimeprec. That is, just trim trailing zeros, and don't > worry about the file system time stamp resolution. The problem > with this approach is that different time stamps for the same > file (atime, mtime, ctime) might show different numbers of digits, > which might cause alignment problems and confusion. > > I'm a bit leery of %.0X as meaning "show more than zero digits > of precision", since .0 always means show zero everywhere else > that printf-style formats are used. Yes it's not ideal. > I'm still not quite following the backward compatibility argument, > as no matter what we do, we'll have different functionality than > before. %#.X outputs an integer time stamp with coreutils 5.97 > and outputs nothing with coreutils 8.6. %.0X is the same as > %#.X, so they're both equally "bad" in that respect. %.*X outputs > "*X" with 5.97 and "?X" with 8.6, so it's not portable either. Yes 8.6 is special in this regard which is why we're trying to release 8.7 quickly so as not to have to worry about it. > It's > not a big deal, but I still mildly prefer the * notation. Well I'm OK with %.0X %#.X or %.*X so I've nothing more to add. cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 12 Nov 2010 11:19:02 GMT) Full text and rfc822 format available.Message #119 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 12 Nov 2010 12:22:53 +0100
Pádraig Brady wrote: > On 11/11/10 17:54, Paul Eggert wrote: ... >> It's >> not a big deal, but I still mildly prefer the * notation. Same here. However, here's an argument for using a different method, perhaps with a hard-coded mapping from common FS types to known precision: Running these two commands with different ordering prints different results. When the file with NS%10 == 0 comes first, stat suppresses the trailing 0(s): $ stat -c '%4n %.*Z' 3 9 3 1289555520.29981438 9 1289555520.300814502 After the first non-multiple-of-10 nanoseconds value, stat prints all trailing 0's: $ stat -c '%4n %.*Z' 9 3 9 1289555520.300814502 3 1289555520.299814380 It's easy to create files like that via e.g., seq 10000|xargs touch -d '1970-01-01 18:43:33.5000000000'
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 12 Nov 2010 13:52:02 GMT) Full text and rfc822 format available.Message #122 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 12 Nov 2010 14:55:51 +0100
Pádraig Brady wrote: >>>>> How about something like this instead? >>>>> >>>>> %.X => precision is 9 (until POSIX goes sub-nanosecond :-) >>>>> %.5X => precision is 5 >>>>> %.*X => precision determined by fstimeprec >>>>> >>>>> Then there's no reason for the "overrides" case. >>>> >>>> Good idea. I prefer that. >> ... >> >> Regardless, of syntax, can any of you suggest a good way to test this? >> I can think of a few, but each has disadvantages. >> >> - mount an ext2 file system and ensure that there are no nanoseconds >> Pro: works all the time, as long as ext2 is an option >> Con: root-only and requires mkfs.ext2 >> >> Code: >> dd if=/dev/zero of=blob count=2 seek=2M > /dev/null || skip=1 >> mkdir mnt || skip=1 >> mkfs -t ext2 -F blob \ >> || skip_test_ "failed to create ext2 file system" >> mount -oloop blob mnt || skip=1 Insert "cd mnt", of course. >> touch -d '1970-01-01 18:43:33.5000000000' k || fail=1 >> test "$(stat -c '%.*Y' k)" = 63813 || fail=1 >> >> - require a modern file system type and run a loop like this, >> hoping to find a time stamp with fewer than "normal" digits of >> nanosecond precision. >> >> $ for i in $(seq 10); do rm -f k; touch -d '1970-01-01 18:43:33.5000000000' k; /cu/src/stat -c "%.*Y" k; done >> 63813.500000000 >> 63813.50000000 >> 63813.500000000 >> 63813.500000000 >> 63813.500000000 >> 63813.50000000 >> 63813.500000000 >> 63813.500000000 >> 63813.500000000 >> 63813.500000000 >> >> Pro: does not require mount privileges >> Con: I suppose it may fail some of the time, no matter how many >> iterations we perform. >> > > I prefer the latter. > It's quick to run so do it 100 times > > require_nanosecond_fs_ > > # Set this to avoid problems with weird time zones. > TZ=UTC0 > export TZ > > # Use a time stamp near the Epoch to avoid trouble with leap seconds. > touch -d '1970-01-01 18:43:33.5' k || framework_failure_ > > prec=$(for i in $(seq 100); do > touch -a k; stat -c "%.*Y" k > done | cut -d. -f2 | wc -L) > test "$prec" = 9 || fail=1 Thanks, but I'm dubious. I ran 1000 iterations of something similar (wc -L computes max length. min length would have worked). touch -d '1970-01-01 18:43:33.5' k for j in $(seq 1000); do printf "$j " for i in $(seq 100); do touch -a k stat -c "%.*Y" k done | grep -c -v '\.500000000$' done |tee out Here's the output. Note that only on the 794'th iteration did I see the first (and only) 0. At this point, I'm leaning towards using the root-only test. iteration #-of-files-with-shortened-NS-count ########### 1 12 2 10 3 11 4 11 5 10 6 14 7 10 8 13 9 7 10 8 11 8 12 11 13 8 14 10 15 11 16 8 17 9 18 11 19 11 20 11 21 10 22 9 23 12 24 10 25 8 26 6 27 10 28 9 29 10 30 11 31 9 32 11 33 9 34 11 35 11 36 9 37 9 38 12 39 11 40 10 41 11 42 10 43 11 44 11 45 10 46 9 47 10 48 10 49 10 50 11 51 15 52 11 53 11 54 10 55 8 56 8 57 9 58 8 59 10 60 9 61 10 62 12 63 10 64 12 65 10 66 7 67 5 68 11 69 9 70 8 71 10 72 12 73 9 74 12 75 8 76 12 77 13 78 12 79 6 80 9 81 9 82 11 83 10 84 11 85 12 86 9 87 9 88 11 89 11 90 10 91 10 92 12 93 9 94 7 95 12 96 7 97 14 98 16 99 13 100 10 101 6 102 14 103 6 104 8 105 12 106 12 107 10 108 9 109 10 110 12 111 11 112 11 113 11 114 10 115 10 116 8 117 7 118 10 119 13 120 9 121 10 122 10 123 9 124 12 125 9 126 9 127 9 128 5 129 13 130 10 131 8 132 12 133 9 134 12 135 13 136 11 137 10 138 9 139 10 140 11 141 9 142 10 143 12 144 13 145 10 146 5 147 8 148 7 149 7 150 7 151 8 152 7 153 8 154 8 155 12 156 11 157 13 158 6 159 11 160 11 161 9 162 10 163 12 164 8 165 11 166 11 167 11 168 5 169 12 170 7 171 13 172 10 173 10 174 12 175 5 176 11 177 10 178 11 179 11 180 9 181 9 182 11 183 9 184 12 185 10 186 9 187 12 188 9 189 5 190 5 191 9 192 8 193 9 194 10 195 9 196 10 197 12 198 10 199 16 200 12 201 9 202 5 203 14 204 9 205 9 206 9 207 11 208 10 209 9 210 11 211 11 212 10 213 7 214 10 215 12 216 8 217 14 218 5 219 9 220 6 221 13 222 10 223 12 224 9 225 10 226 12 227 7 228 12 229 10 230 9 231 11 232 10 233 10 234 6 235 12 236 10 237 9 238 10 239 13 240 12 241 11 242 8 243 7 244 10 245 12 246 9 247 14 248 10 249 8 250 9 251 10 252 8 253 9 254 8 255 12 256 9 257 9 258 9 259 10 260 7 261 12 262 7 263 9 264 7 265 14 266 8 267 12 268 11 269 8 270 12 271 14 272 11 273 12 274 12 275 11 276 9 277 10 278 5 279 14 280 8 281 13 282 9 283 13 284 12 285 9 286 9 287 9 288 10 289 6 290 11 291 13 292 11 293 12 294 11 295 12 296 9 297 10 298 13 299 9 300 9 301 12 302 10 303 9 304 10 305 9 306 12 307 10 308 10 309 7 310 7 311 10 312 10 313 11 314 10 315 11 316 10 317 9 318 11 319 12 320 9 321 15 322 12 323 8 324 10 325 9 326 12 327 12 328 11 329 8 330 10 331 12 332 7 333 9 334 13 335 10 336 9 337 14 338 9 339 8 340 16 341 5 342 6 343 20 344 13 345 9 346 8 347 11 348 9 349 11 350 13 351 11 352 11 353 11 354 10 355 12 356 11 357 10 358 10 359 9 360 14 361 8 362 13 363 12 364 8 365 15 366 13 367 11 368 7 369 12 370 13 371 10 372 9 373 9 374 12 375 12 376 10 377 12 378 14 379 8 380 9 381 8 382 11 383 9 384 18 385 8 386 10 387 7 388 13 389 10 390 14 391 6 392 10 393 8 394 11 395 12 396 11 397 12 398 8 399 12 400 11 401 11 402 9 403 12 404 6 405 11 406 6 407 11 408 13 409 7 410 15 411 13 412 6 413 13 414 4 415 14 416 12 417 7 418 9 419 7 420 11 421 9 422 10 423 10 424 12 425 11 426 12 427 11 428 7 429 10 430 7 431 12 432 8 433 10 434 13 435 11 436 15 437 13 438 13 439 6 440 12 441 8 442 11 443 12 444 12 445 7 446 4 447 11 448 10 449 11 450 7 451 6 452 12 453 12 454 11 455 11 456 9 457 9 458 11 459 11 460 9 461 10 462 8 463 7 464 14 465 5 466 11 467 9 468 10 469 13 470 9 471 7 472 10 473 13 474 12 475 8 476 11 477 11 478 11 479 10 480 5 481 12 482 7 483 8 484 11 485 12 486 12 487 7 488 11 489 13 490 9 491 11 492 10 493 12 494 8 495 12 496 12 497 11 498 8 499 11 500 11 501 11 502 6 503 13 504 9 505 6 506 7 507 11 508 9 509 15 510 13 511 18 512 7 513 9 514 12 515 9 516 12 517 10 518 11 519 9 520 8 521 9 522 11 523 11 524 11 525 13 526 5 527 7 528 9 529 10 530 10 531 10 532 15 533 12 534 6 535 12 536 9 537 9 538 6 539 8 540 11 541 9 542 10 543 9 544 9 545 11 546 8 547 9 548 9 549 9 550 10 551 10 552 12 553 8 554 12 555 4 556 11 557 7 558 11 559 11 560 12 561 13 562 12 563 8 564 10 565 9 566 12 567 11 568 11 569 11 570 7 571 9 572 13 573 7 574 12 575 12 576 10 577 11 578 11 579 14 580 12 581 12 582 12 583 10 584 13 585 12 586 9 587 12 588 10 589 8 590 11 591 9 592 10 593 10 594 11 595 12 596 9 597 10 598 10 599 12 600 7 601 11 602 10 603 9 604 13 605 11 606 9 607 16 608 11 609 10 610 10 611 15 612 8 613 9 614 11 615 11 616 11 617 9 618 3 619 13 620 8 621 11 622 7 623 10 624 8 625 14 626 6 627 13 628 14 629 5 630 8 631 9 632 12 633 5 634 18 635 8 636 10 637 10 638 8 639 11 640 10 641 8 642 10 643 9 644 10 645 12 646 9 647 10 648 11 649 14 650 11 651 10 652 11 653 7 654 15 655 7 656 10 657 10 658 10 659 12 660 7 661 10 662 9 663 8 664 11 665 10 666 10 667 8 668 9 669 7 670 12 671 8 672 9 673 7 674 13 675 9 676 13 677 10 678 4 679 10 680 14 681 10 682 14 683 4 684 13 685 11 686 11 687 5 688 11 689 10 690 10 691 7 692 9 693 12 694 7 695 11 696 12 697 7 698 13 699 13 700 8 701 11 702 11 703 7 704 9 705 13 706 15 707 11 708 10 709 11 710 8 711 10 712 12 713 11 714 7 715 10 716 5 717 12 718 7 719 10 720 11 721 7 722 11 723 7 724 5 725 12 726 12 727 12 728 8 729 5 730 13 731 14 732 9 733 13 734 10 735 12 736 12 737 7 738 10 739 12 740 10 741 11 742 11 743 9 744 7 745 9 746 13 747 9 748 6 749 8 750 10 751 12 752 14 753 7 754 8 755 16 756 10 757 7 758 7 759 7 760 4 761 13 762 7 763 13 764 11 765 10 766 10 767 15 768 8 769 9 770 13 771 10 772 15 773 8 774 6 775 9 776 13 777 6 778 14 779 3 780 11 781 10 782 13 783 9 784 7 785 8 786 8 787 9 788 12 789 12 790 13 791 8 792 14 793 15 794 0 795 8 796 8 797 12 798 15 799 10 800 13 801 11 802 14 803 7 804 9 805 8 806 16 807 9 808 10 809 15 810 4 811 5 812 3 813 10 814 6 815 8 816 5 817 5 818 15 819 14 820 16 821 19 822 6 823 21 824 13 825 12 826 18 827 7 828 7 829 14 830 11 831 15 832 7 833 7 834 8 835 7 836 12 837 9 838 14 839 9 840 8 841 7 842 15 843 5 844 9 845 14 846 8 847 3 848 12 849 13 850 12 851 10 852 12 853 16 854 9 855 12 856 10 857 10 858 15 859 8 860 11 861 12 862 13 863 10 864 19 865 9 866 15 867 6 868 14 869 9 870 7 871 8 872 14 873 9 874 4 875 5 876 11 877 12 878 6 879 10 880 14 881 8 882 6 883 11 884 12 885 5 886 9 887 7 888 9 889 8 890 10 891 10 892 9 893 8 894 9 895 15 896 8 897 10 898 14 899 8 900 8 901 6 902 13 903 5 904 11 905 13 906 7 907 14 908 9 909 11 910 13 911 6 912 13 913 8 914 9 915 8 916 12 917 11 918 9 919 9 920 16 921 11 922 2 923 11 924 11 925 10 926 12 927 13 928 6 929 6 930 9 931 10 932 9 933 14 934 12 935 11 936 9 937 8 938 13 939 9 940 13 941 12 942 8 943 9 944 12 945 16 946 16 947 8 948 11 949 6 950 11 951 13 952 11 953 10 954 3 955 8 956 12 957 7 958 8 959 14 960 13 961 10 962 9 963 13 964 17 965 9 966 9 967 15 968 7 969 10 970 6 971 11 972 13 973 10 974 11 975 11 976 7 977 6 978 12 979 13 980 5 981 10 982 10 983 10 984 8 985 8 986 12 987 11 988 11 989 11 990 16 991 8 992 5 993 6 994 7 995 5 996 11 997 5 998 4 999 5 1000 7
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 12 Nov 2010 14:00:03 GMT) Full text and rfc822 format available.Message #125 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Pádraig Brady <P <at> draigBrady.com> To: Jim Meyering <jim <at> meyering.net> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 12 Nov 2010 14:03:51 +0000
On 12/11/10 11:22, Jim Meyering wrote: > Pádraig Brady wrote: >> On 11/11/10 17:54, Paul Eggert wrote: > ... >>> It's >>> not a big deal, but I still mildly prefer the * notation. > > Same here. > > However, here's an argument for using a different method, perhaps > with a hard-coded mapping from common FS types to known precision: > > Running these two commands with different ordering prints > different results. When the file with NS%10 == 0 comes first, > stat suppresses the trailing 0(s): > > $ stat -c '%4n %.*Z' 3 9 > 3 1289555520.29981438 > 9 1289555520.300814502 > > After the first non-multiple-of-10 nanoseconds value, > stat prints all trailing 0's: > > $ stat -c '%4n %.*Z' 9 3 > 9 1289555520.300814502 > 3 1289555520.299814380 That's just a special case of: find ... | xargs stat ... So it's no worse that differences over multiple runs of stat IMHO As for the general question of using hard coded resolutions for FS types. It might be OK as long as you err'd on the side of too big rather than too small. Though isn't everything going to tend towards nanoseconds going forward? This feature is starting to seem a bit like over engineering for what it gives us TBH. If it was guaranteed to give us an indication of the timestamp resolution, then OK but otherwise I don't think it's worth it. cheers, Pádraig.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 12 Nov 2010 14:09:02 GMT) Full text and rfc822 format available.Message #128 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Pádraig Brady <P <at> draigBrady.com> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 12 Nov 2010 15:12:51 +0100
Pádraig Brady wrote: > On 12/11/10 11:22, Jim Meyering wrote: >> Pádraig Brady wrote: >>> On 11/11/10 17:54, Paul Eggert wrote: >> ... >>>> It's >>>> not a big deal, but I still mildly prefer the * notation. >> >> Same here. >> >> However, here's an argument for using a different method, perhaps >> with a hard-coded mapping from common FS types to known precision: >> >> Running these two commands with different ordering prints >> different results. When the file with NS%10 == 0 comes first, >> stat suppresses the trailing 0(s): >> >> $ stat -c '%4n %.*Z' 3 9 >> 3 1289555520.29981438 >> 9 1289555520.300814502 >> >> After the first non-multiple-of-10 nanoseconds value, >> stat prints all trailing 0's: >> >> $ stat -c '%4n %.*Z' 9 3 >> 9 1289555520.300814502 >> 3 1289555520.299814380 > > That's just a special case of: > find ... | xargs stat ... > So it's no worse that differences over multiple runs of stat IMHO > > As for the general question of using hard coded resolutions for FS types. > It might be OK as long as you err'd on the side of too big rather than too small. > Though isn't everything going to tend towards nanoseconds going forward? > > This feature is starting to seem a bit like over engineering > for what it gives us TBH. If it was guaranteed to give us > an indication of the timestamp resolution, then OK > but otherwise I don't think it's worth it. I agree. I'd like to defer the addition of this feature, at least until it's more predictable. Is that ok with you, Paul?
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Fri, 12 Nov 2010 19:20:03 GMT) Full text and rfc822 format available.Message #131 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Fri, 12 Nov 2010 11:24:19 -0800
On 11/12/2010 06:12 AM, Jim Meyering wrote: > I'd like to defer the addition of this feature, > at least until it's more predictable. > > Is that ok with you, Paul? Doesn't bother me. We can revisit this again in twenty years. Perhaps by then, pathconf will support interrogation of file systems for their time stamp resolutions, as POSIX requires. In the meantime we can add it to 'diff' instead, where it wouldn't be as problematic.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 13 Nov 2010 10:41:02 GMT) Full text and rfc822 format available.Message #134 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 11:45:09 +0100
Paul Eggert wrote: > On 11/12/2010 06:12 AM, Jim Meyering wrote: >> I'd like to defer the addition of this feature, >> at least until it's more predictable. >> >> Is that ok with you, Paul? > > Doesn't bother me. We can revisit this again in twenty years. > Perhaps by then, pathconf will support interrogation of > file systems for their time stamp resolutions, as POSIX requires. > > In the meantime we can add it to 'diff' instead, where it > wouldn't be as problematic. Here's what I'm planning. With this, I'm ready for coreutils-8.7. Debating whether to make another snapshot first. We'll see... From 4a8e9bf14c33b356680298d29f7321d82d4fde5d Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 08:02:02 +0100 Subject: [PATCH 1/3] stat: do not provide variable precision time stamps * src/stat.c: Don't include fstimeprec.c. (out_epoch_sec): Don't call fstimeprec. * NEWS: Update description. * doc/coreutils.texi: Likewise. --- NEWS | 5 +++-- doc/coreutils.texi | 10 +++++----- gnulib | 2 +- src/stat.c | 6 +----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index e77768d..51e0650 100644 --- a/NEWS +++ b/NEWS @@ -24,8 +24,9 @@ GNU coreutils NEWS -*- outline -*- stat's %X, %Y, and %Z directives once again print only the integer part of seconds since the epoch. This reverts a change from coreutils-8.6, that was deemed unnecessarily disruptive. To obtain - a full resolution time stamp for %X, use %.X; if you want (say) just - 3 fractional digits, use %.3X. Likewise for %Y and %Z. + a nanosecond-precision floating point time stamp for %X use %.X; + if you want (say) just 3 fractional digits, use %.3X. Likewise + for %Y and %Z. stat's new %W format directive would print floating point seconds. However, with the above change to %X, %Y and %Z, we've made %W work diff --git a/doc/coreutils.texi b/doc/coreutils.texi index ce56b0e..6a4257f 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10718,10 +10718,10 @@ stat invocation The @samp{%W}, @samp{%X}, @samp{%Y}, and @samp{%Z} formats accept a precision preceded by a period to specify the number of digits to -print after the decimal point. For example, @samp{%.9X} outputs the -last access time to nanosecond precision. If a period is given but no -precision, @command{stat} uses the estimated precision of the file -system. When discarding excess precision, time stamps are truncated +print after the decimal point. For example, @samp{%.3X} outputs the +last access time to millisecond precision. If a period is given but no +precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to +@samp{%.9X} When discarding excess precision, time stamps are truncated toward minus infinity. @example @@ -10737,7 +10737,7 @@ stat invocation $ stat -c '[%.3Y]' /usr [1288929712.114] $ stat -c '[%.Y]' /usr - [1288929712.114951] + [1288929712.114951834] @end example The mount point printed by @samp{%m} is similar to that output diff --git a/gnulib b/gnulib index 4baf5c1..6383a3b 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 4baf5c1e594a65a315fbd5094eaeeb11f4630d18 +Subproject commit 6383a3bbe16d3615791568c030fed5bfe86a4381 diff --git a/src/stat.c b/src/stat.c index ae7ce02..b419f19 100644 --- a/src/stat.c +++ b/src/stat.c @@ -63,7 +63,6 @@ #include "file-type.h" #include "filemode.h" #include "fs.h" -#include "fstimeprec.h" #include "getopt.h" #include "mountlist.h" #include "quote.h" @@ -557,10 +556,7 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, } else { - static struct fstimeprec *tab; - if (! tab) - tab = fstimeprec_alloc (); - precision = fstimeprec (tab, statbuf); + precision = 9; } if (precision && ISDIGIT (dot[-1])) -- 1.7.3.2.4.g60aa9 From ff5fc553f974513e27015faa414fca3603e928e7 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 08:04:13 +0100 Subject: [PATCH 2/3] maint: remove fstimeprec (variable precision time stamp) support The implementation of variable-precision time stamps relied on heuristics that made the output subtly nondeterministic, or at least hard to reproduce: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/21531/focus=21538 So, for now at least, we're removing that feature. * bootstrap.conf (gnulib_modules): Remove fstimeprec. * gl/lib/fstimeprec.c, gl/lib/fstimeprec.h: Remove files. * gl/modules/fstimeprec, gl/modules/fstimeprec-tests: Likewise. * gl/tests/test-fstimeprec.c: Remove file. --- bootstrap.conf | 1 - gl/lib/fstimeprec.c | 178 ------------------------------------------- gl/lib/fstimeprec.h | 22 ----- gl/modules/fstimeprec | 24 ------ gl/modules/fstimeprec-tests | 10 --- gl/tests/test-fstimeprec.c | 74 ------------------ 6 files changed, 0 insertions(+), 309 deletions(-) delete mode 100644 gl/lib/fstimeprec.c delete mode 100644 gl/lib/fstimeprec.h delete mode 100644 gl/modules/fstimeprec delete mode 100644 gl/modules/fstimeprec-tests delete mode 100644 gl/tests/test-fstimeprec.c diff --git a/bootstrap.conf b/bootstrap.conf index 5a6ebae..18ef914 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -85,7 +85,6 @@ gnulib_modules=" freopen freopen-safer fseeko - fstimeprec fsusage fsync ftello diff --git a/gl/lib/fstimeprec.c b/gl/lib/fstimeprec.c deleted file mode 100644 index fd63054..0000000 --- a/gl/lib/fstimeprec.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Determine a file system's time stamp precision. - - Copyright 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* written by Paul Eggert */ - -#include <config.h> -#include "fstimeprec.h" - -#include "hash.h" -#include "stat-time.h" -#include <limits.h> -#include <stdlib.h> - -/* A hash table that maps device numbers to precisions. */ -struct fstimeprec -{ - /* Map device numbers to precisions. */ - struct hash_table *map; - - /* Cache of the most recently allocated and otherwise-unused storage - for probing this table. */ - struct ent *probe; -}; - -/* A pair that maps a device number to a precision. */ -struct ent -{ - dev_t dev; - int prec; -}; - -/* Hash an entry. */ -static size_t -ent_hash (void const *x, size_t table_size) -{ - struct ent const *p = x; - dev_t dev = p->dev; - - /* FIXME: This code is duplicated from di-set.c. */ - /* When DEV is wider than size_t, exclusive-OR the words of DEV into H. - This avoids loss of info, without applying % to the wider type, - which could be quite slow on some systems. */ - size_t h = dev; - unsigned int i; - unsigned int n_words = sizeof dev / sizeof h + (sizeof dev % sizeof h != 0); - for (i = 1; i < n_words; i++) - h ^= dev >> CHAR_BIT * sizeof h * i; - - return h % table_size; -} - -/* Return true if two entries are the same. */ -static bool -ent_compare (void const *x, void const *y) -{ - struct ent const *a = x; - struct ent const *b = y; - return a->dev == b->dev; -} - -/* Using the SET table, map a device to an entry that represents - the file system precision. Return NULL on error. */ -static struct ent * -map_device (struct fstimeprec *tab, dev_t dev) -{ - /* Find space for the probe, reusing the cache if available. */ - struct ent *ent; - struct ent *probe = tab->probe; - if (probe) - { - /* If repeating a recent query, return the cached result. */ - if (probe->dev == dev) - return probe; - } - else - { - tab->probe = probe = malloc (sizeof *probe); - if (! probe) - return NULL; - probe->prec = 0; - } - - /* Probe for the device. */ - probe->dev = dev; - ent = hash_insert (tab->map, probe); - if (ent == probe) - tab->probe = NULL; - return ent; -} - -/* Return a newly allocated table of file system time stamp - resolutions, or NULL if out of memory. */ -struct fstimeprec * -fstimeprec_alloc (void) -{ - struct fstimeprec *tab = malloc (sizeof *tab); - if (tab) - { - enum { INITIAL_DEV_MAP_SIZE = 11 }; - tab->map = hash_initialize (INITIAL_DEV_MAP_SIZE, NULL, - ent_hash, ent_compare, free); - if (! tab->map) - { - free (tab); - return NULL; - } - tab->probe = NULL; - } - return tab; -} - -/* Free TAB. */ -void -fstimeprec_free (struct fstimeprec *tab) -{ - hash_free (tab->map); - free (tab->probe); - free (tab); -} - -/* Using the cached information in TAB, return the estimated precision - of time stamps for the file system containing the file whose status - info is in ST. The returned value counts the number of decimal - fraction digits. Return 0 on failure. - - If TAB is null, the guess is based purely on ST. */ -int -fstimeprec (struct fstimeprec *tab, struct stat const *st) -{ - /* Map the device number to an entry. */ - struct ent *ent = (tab ? map_device (tab, st->st_dev) : NULL); - - /* Guess the precision based on what has been seen so far. */ - int prec = (ent ? ent->prec : 0); - - /* If the current file's timestamp resolution is higher than the - guess, increase the guess. */ - if (prec < 9) - { - struct timespec ats = get_stat_atime (st); - struct timespec mts = get_stat_mtime (st); - struct timespec cts = get_stat_ctime (st); - struct timespec bts = get_stat_birthtime (st); - unsigned int ans = ats.tv_nsec; - unsigned int mns = mts.tv_nsec; - unsigned int cns = cts.tv_nsec; - unsigned int bns = bts.tv_nsec < 0 ? 0 : bts.tv_nsec; - unsigned int power = 10; - int p; - for (p = prec + 1; p < 9; p++) - power *= 10; - - while (ans % power | mns % power | cns % power | bns % power) - { - power /= 10; - prec++; - } - - if (ent) - ent->prec = prec; - } - - return prec; -} diff --git a/gl/lib/fstimeprec.h b/gl/lib/fstimeprec.h deleted file mode 100644 index 8ec24df..0000000 --- a/gl/lib/fstimeprec.h +++ /dev/null @@ -1,22 +0,0 @@ -#include <sys/stat.h> - -#ifndef ATTRIBUTE_MALLOC -# if __GNUC__ >= 3 -# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -# else -# define ATTRIBUTE_MALLOC -# endif -#endif - -#ifndef _GL_ARG_NONNULL -# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 -# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) -# else -# define _GL_ARG_NONNULL(params) -# endif -#endif - -struct fstimeprec *fstimeprec_alloc (void) ATTRIBUTE_MALLOC; -void fstimeprec_free (struct fstimeprec *) _GL_ARG_NONNULL ((1)); -int fstimeprec (struct fstimeprec *, struct stat const *) - _GL_ARG_NONNULL ((2)); diff --git a/gl/modules/fstimeprec b/gl/modules/fstimeprec deleted file mode 100644 index 787c2e7..0000000 --- a/gl/modules/fstimeprec +++ /dev/null @@ -1,24 +0,0 @@ -Description: -estimate precision of time stamps in file systems - -Files: -lib/fstimeprec.c -lib/fstimeprec.h - -Depends-on: -hash -stat-time - -configure.ac: - -Makefile.am: -lib_SOURCES += fstimeprec.c fstimeprec.h - -Include: -"fstimeprec.h" - -License -GPL - -Maintainer: -Paul Eggert and Jim Meyering diff --git a/gl/modules/fstimeprec-tests b/gl/modules/fstimeprec-tests deleted file mode 100644 index bf6b49e..0000000 --- a/gl/modules/fstimeprec-tests +++ /dev/null @@ -1,10 +0,0 @@ -Files: -tests/test-fstimeprec.c - -Depends-on: - -configure.ac: - -Makefile.am: -TESTS += test-fstimeprec -check_PROGRAMS += test-fstimeprec diff --git a/gl/tests/test-fstimeprec.c b/gl/tests/test-fstimeprec.c deleted file mode 100644 index f699139..0000000 --- a/gl/tests/test-fstimeprec.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Test the fstimeprec module. - Copyright (C) 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* written by Paul Eggert */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/stat.h> - -#define ASSERT(expr) \ - do \ - { \ - if (!(expr)) \ - { \ - fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ - fflush (stderr); \ - abort (); \ - } \ - } \ - while (0) - -#include "fstimeprec.h" - -static int -fstimeprec_file (struct fstimeprec *tab, char const *file) -{ - struct stat st; - if (stat (file, &st) != 0) - return 0; - return fstimeprec (tab, &st); -} - -int -main (void) -{ - struct fstimeprec *tab = fstimeprec_alloc (); - ASSERT (tab); - - int m1 = fstimeprec_file (tab, "/"); - int m2 = fstimeprec_file (tab, "."); - int m3 = fstimeprec_file (tab, ".."); - ASSERT (0 <= m1 && m1 <= 9); - ASSERT (0 <= m2 && m2 <= 9); - ASSERT (0 <= m3 && m3 <= 9); - - int n1 = fstimeprec_file (tab, "/"); - int n2 = fstimeprec_file (tab, "."); - int n3 = fstimeprec_file (tab, ".."); - ASSERT (0 <= n1 && n1 <= 9); - ASSERT (0 <= n2 && n2 <= 9); - ASSERT (0 <= n3 && n3 <= 9); - - ASSERT (m1 <= n1); - ASSERT (m2 <= n2); - ASSERT (m3 <= n3); - - fstimeprec_free (tab); - - return 0; -} -- 1.7.3.2.4.g60aa9 From 2d5b3329a2c97a2fee4851d9551ee3d080106765 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 10:12:49 +0100 Subject: [PATCH 3/3] build: update gnulib for linux 2.6.9 nanosleep workaround Also, do the following to avoid "make syntax-check" failure induced by new rules. * .x-sc_bindtextdomain: Exempt files with an #ifdef'd "main". * Makefile.am: Add this file. --- .x-sc_bindtextdomain | 7 +++++++ Makefile.am | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) create mode 100644 .x-sc_bindtextdomain diff --git a/.x-sc_bindtextdomain b/.x-sc_bindtextdomain new file mode 100644 index 0000000..2a568be --- /dev/null +++ b/.x-sc_bindtextdomain @@ -0,0 +1,7 @@ +^gl/lib/randint\.c$ +^gl/tests/test-di-set\.c$ +^gl/tests/test-fadvise\.c$ +^gl/tests/test-ino-map\.c$ +^gl/tests/test-mbsalign\.c$ +^gl/tests/test-rand-isaac\.c$ +^lib/euidaccess-stat\.c$ diff --git a/Makefile.am b/Makefile.am index 9fd5361..b61229d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,6 +41,7 @@ changelog_etc = \ syntax_check_exceptions = \ .x-sc_GPL_version \ + .x-sc_bindtextdomain \ .x-sc_error_message_uppercase \ .x-sc_file_system \ .x-sc_obsolete_symbols \ -- 1.7.3.2.4.g60aa9
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 13 Nov 2010 17:57:01 GMT) Full text and rfc822 format available.Message #137 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 10:01:21 -0800
On 11/13/2010 02:45 AM, Jim Meyering wrote: > Here's what I'm planning. Looks good, thanks, except for NEWS: > + a nanosecond-precision floating point time stamp for %X use %.X; It's fixed-point, not floating point, so I'd remove "floating point". And in coreutils.texi: > +precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to > +@samp{%.9X} When discarding excess precision, time stamps are truncated There's a period missing after the "@samp{%.9X}" (though ideally the sentence would be reworded so as to avoid the need for any period after the sample, as the "%.9X." looks bad when it's printed).
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 13 Nov 2010 17:59:01 GMT) Full text and rfc822 format available.Message #140 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 19:03:30 +0100
Paul Eggert wrote: > On 11/13/2010 02:45 AM, Jim Meyering wrote: > >> Here's what I'm planning. > > Looks good, thanks, except for NEWS: > >> + a nanosecond-precision floating point time stamp for %X use %.X; > > It's fixed-point, not floating point, so I'd remove "floating point". > > And in coreutils.texi: > >> +precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to >> +@samp{%.9X} When discarding excess precision, time stamps are truncated > > There's a period missing after the "@samp{%.9X}" (though ideally the sentence > would be reworded so as to avoid the need for any period after the sample, > as the "%.9X." looks bad when it's printed). Thanks. Unfortunately, I received this about 20 minutes too late to make those changes for the release.
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sat, 13 Nov 2010 21:00:03 GMT) Full text and rfc822 format available.Message #143 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 22:04:31 +0100
Paul Eggert wrote: > On 11/13/2010 02:45 AM, Jim Meyering wrote: > >> Here's what I'm planning. > > Looks good, thanks, except for NEWS: > >> + a nanosecond-precision floating point time stamp for %X use %.X; > > It's fixed-point, not floating point, so I'd remove "floating point". > > And in coreutils.texi: > >> +precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to >> +@samp{%.9X} When discarding excess precision, time stamps are truncated > > There's a period missing after the "@samp{%.9X}" (though ideally the sentence > would be reworded so as to avoid the need for any period after the sample, > as the "%.9X." looks bad when it's printed). "%.9X". doesn't look that bad to me (neither in .info nor in .pdf) How's this, Paul? From f70c7b785b93dd436788d34827b209453157a6f2 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert <at> cs.ucla.edu> Date: Sat, 13 Nov 2010 22:02:29 +0100 Subject: [PATCH] doc: tweak NEWS and coreutils.texi * doc/coreutils.texi (stat invocation): Add sentence-ending period. * NEWS: Correct stat change description: s/floating point //. * cfg.mk (old_NEWS_hash): Update, to match this NEWS change. --- NEWS | 8 ++++---- cfg.mk | 2 +- doc/coreutils.texi | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index a40a0aa..1da7db2 100644 --- a/NEWS +++ b/NEWS @@ -26,10 +26,10 @@ GNU coreutils NEWS -*- outline -*- stat's %X, %Y, and %Z directives once again print only the integer part of seconds since the epoch. This reverts a change from - coreutils-8.6, that was deemed unnecessarily disruptive. To obtain - a nanosecond-precision floating point time stamp for %X use %.X; - if you want (say) just 3 fractional digits, use %.3X. Likewise - for %Y and %Z. + coreutils-8.6, that was deemed unnecessarily disruptive. + To obtain a nanosecond-precision time stamp for %X use %.X; + if you want (say) just 3 fractional digits, use %.3X. + Likewise for %Y and %Z. stat's new %W format directive would print floating point seconds. However, with the above change to %X, %Y and %Z, we've made %W work diff --git a/cfg.mk b/cfg.mk index 244358c..7651ab2 100644 --- a/cfg.mk +++ b/cfg.mk @@ -27,7 +27,7 @@ bootstrap-tools = autoconf,automake,gnulib,bison # Now that we have better tests, make this the default. export VERBOSE = yes -old_NEWS_hash = 24f3cbd2c625a297dc4cfb1b076eeaae +old_NEWS_hash = e2a254a0d4c81397994ea10a15663ac3 # Add an exemption for sc_makefile_at_at_check. _makefile_at_at_check_exceptions = ' && !/^cu_install_program =/' diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 6a4257f..1373f94 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10721,7 +10721,7 @@ stat invocation print after the decimal point. For example, @samp{%.3X} outputs the last access time to millisecond precision. If a period is given but no precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to -@samp{%.9X} When discarding excess precision, time stamps are truncated +@samp{%.9X}. When discarding excess precision, time stamps are truncated toward minus infinity. @example -- 1.7.3.2.4.g60aa9
owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
:bug#7325
; Package coreutils
.
(Sun, 14 Nov 2010 03:05:02 GMT) Full text and rfc822 format available.Message #146 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Paul Eggert <eggert <at> cs.ucla.edu> To: Jim Meyering <jim <at> meyering.net> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 19:09:48 -0800
On 11/13/2010 01:04 PM, Jim Meyering wrote: > "%.9X". doesn't look that bad to me (neither in .info nor in .pdf) > How's this, Paul? Hmm, sorry, I just assumed that it would look bad, but if it looks OK to you then that's fine.
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Sun, 12 Dec 2010 12:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.