diff options
author | bde <bde@FreeBSD.org> | 1995-07-31 00:35:58 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1995-07-31 00:35:58 +0000 |
commit | 3029c788afe81119f71a3c3a7ae9ca00014428a0 (patch) | |
tree | cbc95c828f2184fdca42bfb97779d4a57b8869a1 /sys/kern/vfs_lookup.c | |
parent | fac592af30d777142d6c647a97be7af2f5a73dcb (diff) | |
download | FreeBSD-src-3029c788afe81119f71a3c3a7ae9ca00014428a0.zip FreeBSD-src-3029c788afe81119f71a3c3a7ae9ca00014428a0.tar.gz |
Ignore trailing slashes in pathnames that "refer to a directory",
as is required to be POSIXLY_CORRECT and "right". I interpret
"referring to a directory" as being a directory or becoming a
directory. E.g., the trailing slashes in mkdir("/nonesuch/"),
rename("/tmp", /nonesuch/") and link("/tmp", "/root_can_like_dirs/")
are ignored because the target will become a directory if the
syscall succeeds. A trailing slash on a symlink causes the symlink
to be followed (this is a bug if the symlink doesn't point to a
directory; fix later).
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r-- | sys/kern/vfs_lookup.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index b25745c..e3c7654 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94 - * $Id: vfs_lookup.c,v 1.6 1994/10/06 21:06:36 davidg Exp $ + * $Id: vfs_lookup.c,v 1.7 1995/05/30 08:06:33 rgrimes Exp $ */ #include <sys/param.h> @@ -257,6 +257,7 @@ lookup(ndp) int docache; /* == 0 do not cache last component */ int wantparent; /* 1 => wantparent or lockparent flag */ int rdonly; /* lookup read-only flag bit */ + int trailing_slash; int error = 0; struct componentname *cnp = &ndp->ni_cnd; @@ -302,6 +303,25 @@ dirloop: #endif ndp->ni_pathlen -= cnp->cn_namelen; ndp->ni_next = cp; + + /* + * Replace multiple slashes by a single slash and trailing slashes + * by a null. This must be done before VOP_LOOKUP() because some + * fs's don't know about trailing slashes. Remember if there were + * trailing slashes to handle symlinks, existing non-directories + * and non-existing files that won't be directories specially later. + */ + trailing_slash = 0; + while (*cp == '/' && (cp[1] == '/' || cp[1] == '\0')) { + cp++; + ndp->ni_pathlen--; + if (*cp == '\0') { + trailing_slash = 1; + *ndp->ni_next = '\0'; /* XXX for direnter() ... */ + } + } + ndp->ni_next = cp; + cnp->cn_flags |= MAKEENTRY; if (*cp == '\0' && docache == 0) cnp->cn_flags &= ~MAKEENTRY; @@ -406,6 +426,11 @@ unionlookup: error = EROFS; goto bad; } + if (*cp == '\0' && trailing_slash && + !(cnp->cn_flags & WILLBEDIR)) { + error = ENOENT; + goto bad; + } /* * We return with ni_vp NULL to indicate that the entry * doesn't currently exist, leaving a pointer to the @@ -437,12 +462,21 @@ unionlookup: * Check for symbolic link */ if ((dp->v_type == VLNK) && - ((cnp->cn_flags & FOLLOW) || *ndp->ni_next == '/')) { + ((cnp->cn_flags & FOLLOW) || trailing_slash || + *ndp->ni_next == '/')) { cnp->cn_flags |= ISSYMLINK; return (0); } /* + * Check for bogus trailing slashes. + */ + if (trailing_slash && dp->v_type != VDIR) { + error = ENOTDIR; + goto bad2; + } + + /* * Check to see if the vnode has been mounted on; * if so find the root of the mounted file system. */ |