Return to BSD News archive
Newsgroups: comp.os.386bsd.bugs
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!dog.ee.lbl.gov!hellgate.utah.edu!fcom.cc.utah.edu!cs.weber.edu!terry
From: terry@cs.weber.edu (A Wizard of Earth C)
Subject: Re: patch for bin/rm/rm.c
Message-ID: <1993Mar24.222133.14022@fcom.cc.utah.edu>
Sender: news@fcom.cc.utah.edu
Organization: Weber State University (Ogden, UT)
References: <1oligtINN6mj@ftp.UU.NET> <f0Yl6J8@quack.kfu.com> <CGD.93Mar23164609@erewhon.CS.Berkeley.EDU>
Date: Wed, 24 Mar 93 22:21:33 GMT
Lines: 119
In article <CGD.93Mar23164609@erewhon.CS.Berkeley.EDU> cgd@erewhon.CS.Berkeley.EDU (Chris G. Demetriou) writes:
>In article <f0Yl6J8@quack.kfu.com> dfox@quack.kfu.com (David Fox) writes:
>>I'm not sure if this is the way it's supposed
>>to work.
>
>that is the correct behavior for rmdir.
>
>rmdir foo/
>
>is equivalent to
>
>rmdir foo/.
>
>which, it should be obvious is an impossibility; you can't delete a
>dir that you're holding busy, and you "enter" it with the trailing /.
Sorry, Chris, but this isn't true. POSIX behaviour is to ignore doubled
or trailing slashes. The difference is between a path component seperator
and a path component terminator. The offending code is fixed in namei for
symbolic links:
/*
* Check if root directory should replace current directory.
* Done at start of translation and after symbolic link.
*/
ndp->ni_ptr = ndp->ni_pnbuf;
if (*ndp->ni_ptr == '/') {
vrele(dp);
>>>HERE>>>>>>>>>>>> while (*ndp->ni_ptr == '/') {
ndp->ni_ptr++;
ndp->ni_pathlen--;
}
dp = ndp->ni_rootdir;
VREF(dp);
}
The same isn't done for normal file names during lookup:
dirloop:
/*
* Search a new directory.
*
* The ni_hash value is for use by vfs_cache.
* The last component of the filename is left accessible via
* ndp->ptr for callers that need the name. Callers needing
* the name set the SAVENAME flag. When done, they assume
* responsibility for freeing the pathname buffer.
*/
ndp->ni_hash = 0;
for (cp = ndp->ni_ptr; *cp != 0 && *cp != '/'; cp++)
ndp->ni_hash += (unsigned char)*cp;
>>>SHOULD BE INSERTED HERE>>>>>>>>>>>>>>>>>>
ndp->ni_namelen = cp - ndp->ni_ptr;
if (ndp->ni_namelen >= NAME_MAX) {
error = ENAMETOOLONG;
goto bad;
}
The failure occurs because the name is incorrectly determined to be a
"degenerate" name:
/*
* Check for degenerate name (e.g. / or "")
* which is a way of talking about a directory,
* e.g. like "/." or ".".
*/
>>>>>>ndp->ni_ptr[0] HAS INCORRECT VALUE HERE>>>>>>>>>>>>
if (ndp->ni_ptr[0] == '\0') {
if (flag != LOOKUP || wantparent) {
error = EISDIR;
goto bad;
}
In SVR4, the removal of trailing slashes is done automatically (by some
code similar to that for symbolic links).
In SunOS, the trailing slashes are removed in a way that would make you
expect it to operate like SVR4; however, although a trailing slash is
seen as an explicit tag that the file *must* be a directory, functions
for manipulating directories fail:
% mkdir foo
% ls -ld foo
drwxrwxr-x 2 terry 512 Mar 24 15:12 foo
% rmdir foo/
rmdir: foo/: Invalid argument <<<<<<<<<<#1!!!!!!!!!!!!!!!!
% rm foo
rm: foo is a directory
% rm foo/
rm: foo/ is a directory
% rmdir foo
% touch foo
% rmdir foo
rmdir: foo: Not a directory <<<<<<<<<<#2!!!!!!!!!!!!!!!!
% rmdir foo/
rmdir: foo/: Not a directory
% rm foo/
rm: foo/: Not a directory <<<<<<<<<<#3!!!!!!!!!!!!!!!!
% rm foo
In other words, in SunOS, cases 1, 2, and 3 are inconsistant.
I believe we should follow the SVR4 model on this one, since it seems the
wave of the future is POSIX compliance.
What does everyone else think, before I go off and make the obvious patch?
Terry Lambert
terry@icarus.weber.edu
terry_lambert@novell.com
---
Any opinions in this posting are my own and not those of my present
or previous employers.
--
-------------------------------------------------------------------------------
"I have an 8 user poetic license" - me
Get the 386bsd FAQ from agate.berkeley.edu:/pub/386BSD/386bsd-0.1/unofficial
-------------------------------------------------------------------------------