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

From: Pádraig Brady <[email-masked]>
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