Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Feb 2010 05:47:19 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Poul-Henning Kamp <phk@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r203990 - head/lib/libc/sys
Message-ID:  <20100218044931.S95007@delplex.bde.org>
In-Reply-To: <201002170911.o1H9BL6m095996@svn.freebsd.org>
References:  <201002170911.o1H9BL6m095996@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 17 Feb 2010, Poul-Henning Kamp wrote:

> Log:
>  Mention EISDIR as a possible errno.

It's not a possible error.

> Modified:
>  head/lib/libc/sys/unlink.2
>
> Modified: head/lib/libc/sys/unlink.2
> ==============================================================================
> --- head/lib/libc/sys/unlink.2	Wed Feb 17 09:09:12 2010	(r203989)
> +++ head/lib/libc/sys/unlink.2	Wed Feb 17 09:11:21 2010	(r203990)
> @@ -114,6 +114,8 @@ succeeds unless:
> .Bl -tag -width Er
> .It Bq Er ENOTDIR
> A component of the path prefix is not a directory.
> +.It Bq Er EISDIR
> +The named file is a directory.
> .It Bq Er ENAMETOOLONG
> A component of a pathname exceeded 255 characters,
> or an entire path name exceeded 1023 characters.

According to the POSIX spec (old draft, current version is the same):

%%%
48397              [EPERM]              The file named by path is a directory, and either the calling process does not
48398                                   have appropriate privileges, or the implementation prohibits using unlink( )
48399                                   on directories.
                    [EISDIR]             [not mentioned for unlink()]
%%%

According to unlink.2:
%%%
      [EPERM]            The named file is a directory.
      [EISDIR]           [previously not mentioned]
%%%

According to the source code: in kern_unlinkat():

% 	if (vp->v_type == VDIR && oldinum == 0) {
% 		error = EPERM;		/* POSIX */
% 	} else if (oldinum != 0 &&
% 		  ((error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td)) == 0) &&
% 		  sb.st_ino != oldinum) {
% 			error = EIDRM;	/* Identifier removed */
% 	} else {

`oldinum' is always 0 for unlink(2).  Thus the code matches the specified
and previously-documented behaviour.  FreeBSD is still choosing to implement
the second possibility of the spec (that the implementation prohibits using
unlink() on directories) (except the first possibility allows this too --
appropriate privilege can mean "more privilege than anyone has").  The
difference may be a difference in FreeBSD since trying to use appropriate
privilege may have side effects, but it isn't required to be a difference
in POSIX.

`oldinum' is also always 0 for unlinkat(2).  It seems to be only nonzero
for the ffs_fsck sysctl.  I guess this sysctl is undocumented and its
EIDRM error is even less documented.

The oldinum code has bad style:
- weird indentation for both continued lines.  Far from KNF (-ci4).  Closer
   to -lp, but off-by 1 char for that.
- banal comment.

The "POSIX" comment for oldinum == 0 is banal and misleading too.  POSIX
does specify the errno as EPERM, but the only possibly-surprising thing
about this errno is that it occurs for the superuser too, not what it is.
Once upon a time, FreeBSD implemented the first possibility, with
appropriate privilege meaning that only the superuser can try to
unlink() (might still fail due to a leaf file system not liking it).
Then the errno of EPERM was generic for lack of appropriate privelege
and not commented on.  Only the superuse case changed, and the comment
misleads by documenting something banal instead of that.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100218044931.S95007>