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 -------------------------------------------------------------------------------