truncate and open(O_TRUNC) times.

Jilles Tjoelker jilles at
Mon Jul 29 20:50:19 UTC 2013

On Mon, Jul 29, 2013 at 06:38:21AM +1000, Chris Johns wrote:
> In the RTEMS project we have some test code that appears to fail on 
> FreeBSD. You can find a stripped down version at 

> The code does ..

>    fd = open (file01, O_CREAT | O_WRONLY, mode);
>    n = write (fd, databuf, len);
>    assert (n == len);
>    status = close (fd);
>    assert (status == 0);
>    sleep(2);
>    status = truncate (file01, len);
>    assert (status == 0);

> The length does not change and given the file does not change our 
> interpretation of the truncate call is the times should not change.

> In the case of ..

>    fd = open (file03, O_CREAT | O_WRONLY, mode);
>    status = close (fd);
>    assert (status == 0);
>    sleep(2);
>    fd = open (file03, O_TRUNC | O_WRONLY, mode);
>    status = close (fd);
>    assert (status == 0);

> the times do change as expected.

Although POSIX indeed makes an exception for truncate() (ftruncate() and
open(O_TRUNC) update the times whenever successful), this inconsistency
has been reported as a bug to the Austin Group and this has been
accepted. The report is
specifically about truncate() and asks to change its specification to
update the times whenever successful; changes all metadata-changing
operations to update the times whenever successful, even when the new
value is equal to the old value, except chown() where both uid and gid
are -1 and futimens()/utimensat() where both times have UTIME_OMIT. In
those special cases, the implementation may or may not update the times.

Some browsing around on shows inconsistent descriptions
in the man pages as well. Usually, ftruncate() and truncate() are
described in the same man page and there is no mention of any difference
in the way they affect timestamps.

FreeBSD's truncate() already behaves as proposed in the Austin Group
bugs; I think it is best to keep it that way.

Jilles Tjoelker

More information about the freebsd-standards mailing list