Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!mit-eddie!ll-xn!ames!oliveb!pyramid!uccba!hal!ncoast!allbery From: allbery@ncoast.UUCP (Brandon Allbery) Newsgroups: comp.unix.wizards Subject: Re: /bin/test and stat(2) Message-ID: <4779@ncoast.UUCP> Date: Wed, 30-Sep-87 19:13:39 EDT Article-I.D.: ncoast.4779 Posted: Wed Sep 30 19:13:39 1987 Date-Received: Mon, 5-Oct-87 02:28:24 EDT References: <9479@brl-adm.ARPA> Reply-To: allbery@ncoast.UUCP (Brandon Allbery) Followup-To: comp.unix.wizards Organization: Cleveland Public Access UN*X, Cleveland, Oh Lines: 50 As quoted from <9479@brl-adm.ARPA> by franco@MIKEY.BBN.COM (Frank A. Lonigro): +--------------- | I understand that the 'stat' system call on a NULL string for a file name | will default to '.' (DOT), the current directory. You don't have to explain | to me why this is. I already know why. I only just recently discovered | this fact. But what I would like to know is, why does the test -d of a | NULL string in the following sample script return true? | | Foo="" | if test -d "$Foo" | then | do something constructive | fi +--------------- Both "stat" and this sample demonstrate what is basically a bug in the kernel routine namei(), which maps a filename to a pair. The pseudocode for namei() is as follows: pathp = pathname; if (*pathp == '/') { pathp++; /* skip the leading `/' */ inode = u.u_rdir; /* calling proc's root dir */ } else inode = u.u_cdir; /* calling proc's current dir */ while (scan_to_a_slash_or_end_of_the_path(&pathp, name)) inode = get_named_inode_in_dir_inode(name); return inode; Notice that there is no check for a null pathname: this means that, since the first character of the path is not `/' the inode is initially set to the current directory; and since there is no file name following the start of the path the while loop always fails. So namei() happily returns the value of u.u_cdir -- the current directory. [DISCLAIMER: The pseudocode above comes from my understanding of the problem; it is NOT based on any AT&T or UCB CSRG code. Baseides, the only namei()-type code I've ever seen is in Minix, and it's done differently there.] Some, but most definitely NOT all, versions of Unix explicitly check for a null path in namei() and return an error (ENOENT, or perhaps EINVAL). All others have the bug; since it's not exactly crippling, it's not considered a high priority to fix it, so it stays. -- Brandon S. Allbery, moderator of comp.sources.misc {{harvard,mit-eddie}!necntc,well!hoptoad,sun!mandrill!hal}!ncoast!allbery ARPA: necntc!ncoast!allbery@harvard.harvard.edu Fido: 157/502 MCI: BALLBERY <> "`You left off the thunderclap and the lightning flash.', I told him. `Should I try again?' `Never mind.'" --Steven Brust, JHEREG