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).
This commit is contained in:
parent
fac592af30
commit
3029c788af
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.27 1995/06/28 12:00:57 davidg Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.28 1995/07/13 08:47:42 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -834,6 +834,8 @@ link(p, uap, retval)
|
||||
(error = suser(p->p_ucred, &p->p_acflag)) == 0) {
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT;
|
||||
if (vp->v_type == VDIR)
|
||||
nd.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
nd.ni_dirp = uap->link;
|
||||
error = namei(&nd);
|
||||
if (!error) {
|
||||
@ -1819,6 +1821,8 @@ rename(p, uap, retval)
|
||||
fvp = fromnd.ni_vp;
|
||||
NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART,
|
||||
UIO_USERSPACE, uap->to, p);
|
||||
if (fromnd.ni_vp->v_type == VDIR)
|
||||
tond.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
error = namei(&tond);
|
||||
if (error) {
|
||||
VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
|
||||
@ -1904,6 +1908,7 @@ mkdir(p, uap, retval)
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
|
||||
nd.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
error = namei(&nd);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -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 @@ lookup(ndp)
|
||||
#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 @@ lookup(ndp)
|
||||
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,11 +462,20 @@ lookup(ndp)
|
||||
* 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.
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.27 1995/06/28 12:00:57 davidg Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.28 1995/07/13 08:47:42 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -834,6 +834,8 @@ link(p, uap, retval)
|
||||
(error = suser(p->p_ucred, &p->p_acflag)) == 0) {
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT;
|
||||
if (vp->v_type == VDIR)
|
||||
nd.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
nd.ni_dirp = uap->link;
|
||||
error = namei(&nd);
|
||||
if (!error) {
|
||||
@ -1819,6 +1821,8 @@ rename(p, uap, retval)
|
||||
fvp = fromnd.ni_vp;
|
||||
NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART,
|
||||
UIO_USERSPACE, uap->to, p);
|
||||
if (fromnd.ni_vp->v_type == VDIR)
|
||||
tond.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
error = namei(&tond);
|
||||
if (error) {
|
||||
VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
|
||||
@ -1904,6 +1908,7 @@ mkdir(p, uap, retval)
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
|
||||
nd.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
error = namei(&nd);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)namei.h 8.2 (Berkeley) 1/4/94
|
||||
* $Id: namei.h,v 1.5 1995/03/09 20:27:21 phk Exp $
|
||||
* $Id: namei.h,v 1.6 1995/07/29 11:42:49 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_NAMEI_H_
|
||||
@ -134,6 +134,7 @@ struct nameidata {
|
||||
#define MAKEENTRY 0x04000 /* entry is to be added to name cache */
|
||||
#define ISLASTCN 0x08000 /* this is last component of pathname */
|
||||
#define ISSYMLINK 0x10000 /* symlink needs interpretation */
|
||||
#define WILLBEDIR 0x20000 /* new files will be dirs; allow trailing / */
|
||||
#define PARAMASK 0xfff00 /* mask of parameter descriptors */
|
||||
/*
|
||||
* Initialization of an nameidata structure.
|
||||
|
Loading…
Reference in New Issue
Block a user