Subject: bug#7325: new test failure due to non-portability of printf formats like %05.3s

From: Jim Meyering <[email-masked]>
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.