cvs commit: src/sys/ufs/ufs ufs_vnops.c
bde at zeta.org.au
Thu Jun 1 15:11:24 UTC 2006
On Thu, 1 Jun 2006, Ceri Davies wrote:
> On Thu, Jun 01, 2006 at 12:05:23PM +0930, Greg 'groggy' Lehey wrote:
>> On Wednesday, 31 May 2006 at 13:15:29 +0000, Maxim Konovalov wrote:
>>> maxim 2006-05-31 13:15:29 UTC
>>> FreeBSD src repository
>>> Modified files:
>>> sys/ufs/ufs ufs_vnops.c
>>> o According to POSIX, the result of ftruncate(2) is unspecified
>>> for file types other than VREG, VDIR and shared memory objects.
>>> We already handle VREG, VLNK and VDIR cases. Silently ignore
>>> Revision Changes Path
>>> 1.276 +22 -4 src/sys/ufs/ufs/ufs_vnops.c
>> Is this worth a man page update?
Only to the extent that the man page is generally broken. It has
always tried to document the behaviour now implemented in ffs but it
omits some details and is not clear on the [EROFS] case. The commit
makes the man page actually agree with one file system (ffs; file
systems cut and pasted from ffs, e.g., ext2fs, still panic).
> Undoubtedly. Does the attached look like enough? I'm not sure if we
> want to add a STANDARDS section for this when it's valid behaviour.
> Index: src/lib/libc/sys/truncate.2
> RCS file: /home/ncvs/src/lib/libc/sys/truncate.2,v
> retrieving revision 1.17
> diff -u -r1.17 truncate.2
> --- src/lib/libc/sys/truncate.2 20 Jan 2005 09:17:05 -0000 1.17
> +++ src/lib/libc/sys/truncate.2 1 Jun 2006 09:47:19 -0000
> @@ -69,6 +69,10 @@
> the file must be open for writing.
> .Sh RETURN VALUES
> .Rv -std
> +If the file to be modified is not a directory or
> +a regular file, the
> +.Fn truncate
> +call will return the value 0.
> .Sh ERRORS
> .Fn truncate
The man page already says this (in standard wording in ".Rv -std" and
% RETURN VALUES
% Upon successful completion, the value 0 is returned; otherwise the
% value -1 is returned and the global variable errno is set to indicate the
% The truncate() system call succeeds unless:
% [... various unrelated errors]
% [EISDIR] The named file is a directory.
This covers the behaviour for directories in more detail.
% [EROFS] The named file resides on a read-only file system.
I originally misinterpreted "resides" as strictly applying to the name of
a fifo (since fifo contents don't really reside anywhere) but it obviously
should only apply to the contents. open(2) uses the same wording.
The actual behaviour was (and still is on some file systems containing code
cut and pasted from ffs, e.g., ext2fs):
- [f]truncate() of a fifo on a r/w file system (for ffs and clones) acts as
if there were a resource fork of the file, with one half of the fork
containing the fifo and the other half containing a irregular file, where
an irregular file in this context is a regular file that is inaccessible
from userland except via stat(2) and statfs(2) to see some of its side
effects, and via unlink(2) to clean it up. This used to be a small
problem. However, some versions of FreeBSD have debugging code that
panics on attempts to truncate the irregular file.
- I thinl [f]truncate() of a fifo on a r/o file system panics unless the
new size is 0.
% [... various unrelated errors]
% The ftruncate() system call succeeds unless:
% [EBADF] The fd argument is not a valid descriptor.
% [EINVAL] The fd argument references a socket, not a file.
% [EINVAL] The fd descriptor is not open for writing.
Note that there is no !directory or r/o restrictions here. These
restrictions are in in open(2).
There is an additional restriction here for sockets. Either this or
the lack of such a restriction for truncate(2) must be a bug, since
sockets may be bound to file systems and whether truncation succeeds
shouldn't depend on the syscall used to do it.
% Use of truncate() to extend a file is not portable.
This can only be a bug in programs which assume that extension using
[f]truncate() is portable, not in [f]truncate(). (File) extension is an
XSI (specification) extension in POSIX.
The main bugs here are:
- truncate.2 doesn't say that except for regular files, success consists
of doing nothing (even when the caller asks for something to be done).
- truncate.2 doesn't say that for regular files, certain timestamps
(mainly ctime) are set on successful completion (even when the caller
asks for nothing to be done). It shares this bug with most or all
FreeBSD man pages for fs syscalls. POSIX is much more careful about
such details. POSIX may be harder to read because it is more formal,
but when detail is just absent in an informal description it is
impossible to recover from the description.
More information about the cvs-src